69 #include "llvm/IR/IntrinsicsPowerPC.h"
102 using namespace llvm;
104 #define DEBUG_TYPE "ppc-lowering"
110 cl::desc(
"disable setting the node scheduling preference to ILP on PPC"),
cl::Hidden);
131 STATISTIC(ShufflesHandledWithVPERM,
"Number of shuffles lowered to a VPERM");
132 STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
146 bool isPPC64 = Subtarget.
isPPC64();
210 if (!Subtarget.
hasSPE()) {
219 for (
MVT VT : ScalarIntVTs) {
229 if (isPPC64 || Subtarget.
hasFPCVT()) {
387 !(TM.Options.UnsafeFPMath && Subtarget.
hasFRSQRTE() &&
392 !(TM.Options.UnsafeFPMath && Subtarget.
hasFRSQRTES() &&
501 if (TM.Options.UnsafeFPMath) {
723 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
951 if (TM.Options.UnsafeFPMath) {
1247 if (Subtarget.
hasMMA()) {
1422 if (MaxAlign == MaxMaxAlign)
1424 if (
VectorType *VTy = dyn_cast<VectorType>(Ty)) {
1425 if (MaxMaxAlign >= 32 &&
1426 VTy->getPrimitiveSizeInBits().getFixedSize() >= 256)
1427 MaxAlign =
Align(32);
1428 else if (VTy->getPrimitiveSizeInBits().getFixedSize() >= 128 &&
1430 MaxAlign =
Align(16);
1431 }
else if (
ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
1434 if (EltAlign > MaxAlign)
1435 MaxAlign = EltAlign;
1436 }
else if (
StructType *STy = dyn_cast<StructType>(Ty)) {
1437 for (
auto *EltTy : STy->elements()) {
1440 if (EltAlign > MaxAlign)
1441 MaxAlign = EltAlign;
1442 if (MaxAlign == MaxMaxAlign)
1457 return Alignment.
value();
1465 return Subtarget.
hasSPE();
1487 return "PPCISD::FP_TO_UINT_IN_VSR,";
1489 return "PPCISD::FP_TO_SINT_IN_VSR";
1493 return "PPCISD::FTSQRT";
1495 return "PPCISD::FSQRT";
1500 return "PPCISD::XXSPLTI_SP_TO_DP";
1502 return "PPCISD::XXSPLTI32DX";
1537 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1539 return "PPCISD::ANDI_rec_1_EQ_BIT";
1541 return "PPCISD::ANDI_rec_1_GT_BIT";
1556 return "PPCISD::ST_VSR_SCAL_INT";
1581 return "PPCISD::PADDI_DTPREL";
1598 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1600 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1608 return "PPCISD::STRICT_FADDRTZ";
1610 return "PPCISD::STRICT_FCTIDZ";
1612 return "PPCISD::STRICT_FCTIWZ";
1614 return "PPCISD::STRICT_FCTIDUZ";
1616 return "PPCISD::STRICT_FCTIWUZ";
1618 return "PPCISD::STRICT_FCFID";
1620 return "PPCISD::STRICT_FCFIDU";
1622 return "PPCISD::STRICT_FCFIDS";
1624 return "PPCISD::STRICT_FCFIDUS";
1650 return CFP->getValueAPF().isZero();
1654 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(
CP->getConstVal()))
1655 return CFP->getValueAPF().isZero();
1663 return Op < 0 ||
Op == Val;
1675 if (ShuffleKind == 0) {
1678 for (
unsigned i = 0; i != 16; ++i)
1681 }
else if (ShuffleKind == 2) {
1684 for (
unsigned i = 0; i != 16; ++i)
1687 }
else if (ShuffleKind == 1) {
1688 unsigned j = IsLE ? 0 : 1;
1689 for (
unsigned i = 0; i != 8; ++i)
1706 if (ShuffleKind == 0) {
1709 for (
unsigned i = 0; i != 16; i += 2)
1713 }
else if (ShuffleKind == 2) {
1716 for (
unsigned i = 0; i != 16; i += 2)
1720 }
else if (ShuffleKind == 1) {
1721 unsigned j = IsLE ? 0 : 2;
1722 for (
unsigned i = 0; i != 8; i += 2)
1748 if (ShuffleKind == 0) {
1751 for (
unsigned i = 0; i != 16; i += 4)
1757 }
else if (ShuffleKind == 2) {
1760 for (
unsigned i = 0; i != 16; i += 4)
1766 }
else if (ShuffleKind == 1) {
1767 unsigned j = IsLE ? 0 : 4;
1768 for (
unsigned i = 0; i != 8; i += 4)
1785 unsigned LHSStart,
unsigned RHSStart) {
1788 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1789 "Unsupported merge size!");
1791 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1792 for (
unsigned j = 0; j != UnitSize; ++j) {
1794 LHSStart+j+i*UnitSize) ||
1796 RHSStart+j+i*UnitSize))
1811 if (ShuffleKind == 1)
1813 else if (ShuffleKind == 2)
1818 if (ShuffleKind == 1)
1820 else if (ShuffleKind == 0)
1836 if (ShuffleKind == 1)
1838 else if (ShuffleKind == 2)
1843 if (ShuffleKind == 1)
1845 else if (ShuffleKind == 0)
1895 unsigned RHSStartValue) {
1899 for (
unsigned i = 0; i < 2; ++i)
1900 for (
unsigned j = 0; j < 4; ++j)
1902 i*RHSStartValue+j+IndexOffset) ||
1904 i*RHSStartValue+j+IndexOffset+8))
1926 unsigned indexOffset = CheckEven ? 4 : 0;
1927 if (ShuffleKind == 1)
1929 else if (ShuffleKind == 2)
1935 unsigned indexOffset = CheckEven ? 0 : 4;
1936 if (ShuffleKind == 1)
1938 else if (ShuffleKind == 0)
1961 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
1964 if (i == 16)
return -1;
1969 if (ShiftAmt < i)
return -1;
1974 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
1976 for (++i; i != 16; ++i)
1979 }
else if (ShuffleKind == 1) {
1981 for (++i; i != 16; ++i)
1988 ShiftAmt = 16 - ShiftAmt;
1998 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2002 if (
N->getMaskElt(0) % EltSize != 0)
2007 unsigned ElementBase =
N->getMaskElt(0);
2010 if (ElementBase >= 16)
2015 for (
unsigned i = 1; i != EltSize; ++i)
2016 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2019 for (
unsigned i = EltSize,
e = 16; i !=
e; i += EltSize) {
2020 if (
N->getMaskElt(i) < 0)
continue;
2021 for (
unsigned j = 0; j != EltSize; ++j)
2022 if (
N->getMaskElt(i+j) !=
N->getMaskElt(j))
2040 "Unexpected element width.");
2041 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2043 unsigned NumOfElem = 16 /
Width;
2044 unsigned MaskVal[16];
2045 for (
unsigned i = 0; i < NumOfElem; ++i) {
2046 MaskVal[0] =
N->getMaskElt(i *
Width);
2047 if ((StepLen == 1) && (MaskVal[0] %
Width)) {
2049 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) %
Width)) {
2053 for (
unsigned int j = 1; j <
Width; ++j) {
2054 MaskVal[j] =
N->getMaskElt(i *
Width + j);
2055 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2065 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2070 unsigned M0 =
N->getMaskElt(0) / 4;
2071 unsigned M1 =
N->getMaskElt(4) / 4;
2072 unsigned M2 =
N->getMaskElt(8) / 4;
2073 unsigned M3 =
N->getMaskElt(12) / 4;
2074 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2075 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2080 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2081 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2082 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2083 InsertAtByte = IsLE ? 12 : 0;
2088 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2089 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2090 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2091 InsertAtByte = IsLE ? 8 : 4;
2096 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2097 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2098 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2099 InsertAtByte = IsLE ? 4 : 8;
2104 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2105 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2106 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2107 InsertAtByte = IsLE ? 0 : 12;
2114 if (
N->getOperand(1).isUndef()) {
2117 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2118 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2119 InsertAtByte = IsLE ? 12 : 0;
2122 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2123 InsertAtByte = IsLE ? 8 : 4;
2126 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2127 InsertAtByte = IsLE ? 4 : 8;
2130 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2131 InsertAtByte = IsLE ? 0 : 12;
2140 bool &Swap,
bool IsLE) {
2147 unsigned M0 =
N->getMaskElt(0) / 4;
2148 unsigned M1 =
N->getMaskElt(4) / 4;
2149 unsigned M2 =
N->getMaskElt(8) / 4;
2150 unsigned M3 =
N->getMaskElt(12) / 4;
2154 if (
N->getOperand(1).isUndef()) {
2155 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2156 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2159 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2165 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2169 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2174 ShiftElts = (8 -
M0) % 8;
2175 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2180 ShiftElts = (4 -
M0) % 4;
2185 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2190 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2207 for (
int i = 0; i < 16; i +=
Width)
2208 if (
N->getMaskElt(i) != i +
Width - 1)
2239 bool &Swap,
bool IsLE) {
2246 unsigned M0 =
N->getMaskElt(0) / 8;
2247 unsigned M1 =
N->getMaskElt(8) / 8;
2248 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2252 if (
N->getOperand(1).isUndef()) {
2253 if ((
M0 |
M1) < 2) {
2254 DM = IsLE ? (((~
M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2262 if (
M0 > 1 &&
M1 < 2) {
2264 }
else if (M0 < 2 && M1 > 1) {
2272 DM = (((~
M1) & 1) << 1) + ((~
M0) & 1);
2275 if (M0 < 2 && M1 > 1) {
2277 }
else if (
M0 > 1 &&
M1 < 2) {
2285 DM = (
M0 << 1) + (
M1 & 1);
2299 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2315 unsigned EltSize = 16/
N->getNumOperands();
2316 if (EltSize < ByteSize) {
2317 unsigned Multiple = ByteSize/EltSize;
2319 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2322 for (
unsigned i = 0,
e =
N->getNumOperands(); i !=
e; ++i) {
2323 if (
N->getOperand(i).isUndef())
continue;
2325 if (!isa<ConstantSDNode>(
N->getOperand(i)))
return SDValue();
2327 if (!UniquedVals[i&(Multiple-1)].getNode())
2328 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2329 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2339 bool LeadingZero =
true;
2340 bool LeadingOnes =
true;
2341 for (
unsigned i = 0; i != Multiple-1; ++i) {
2342 if (!UniquedVals[i].getNode())
continue;
2349 if (!UniquedVals[Multiple-1].getNode())
2351 int Val = cast<ConstantSDNode>(UniquedVals[Multiple-1])->getZExtValue();
2356 if (!UniquedVals[Multiple-1].getNode())
2358 int Val =cast<ConstantSDNode>(UniquedVals[Multiple-1])->getSExtValue();
2367 for (
unsigned i = 0,
e =
N->getNumOperands(); i !=
e; ++i) {
2368 if (
N->getOperand(i).isUndef())
continue;
2370 OpVal =
N->getOperand(i);
2371 else if (OpVal !=
N->getOperand(i))
2377 unsigned ValSizeInBytes = EltSize;
2380 Value = CN->getZExtValue();
2382 assert(CN->getValueType(0) ==
MVT::f32 &&
"Only one legal FP vector type!");
2389 if (ValSizeInBytes < ByteSize)
return SDValue();
2400 if (MaskVal == 0)
return SDValue();
2403 if (SignExtend32<5>(MaskVal) == MaskVal)
2417 if (!isa<ConstantSDNode>(
N))
2420 Imm = (int16_t)cast<ConstantSDNode>(
N)->getZExtValue();
2422 return Imm == (int32_t)cast<ConstantSDNode>(
N)->getZExtValue();
2424 return Imm == (int64_t)cast<ConstantSDNode>(
N)->getZExtValue();
2438 if (
MemSDNode *Memop = dyn_cast<MemSDNode>(*UI)) {
2439 if (Memop->getMemoryVT() ==
MVT::f64) {
2440 Base =
N.getOperand(0);
2453 if (!isa<ConstantSDNode>(
N))
2456 Imm = (int64_t)cast<ConstantSDNode>(
N)->getZExtValue();
2457 return isInt<34>(Imm);
2484 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2489 Base =
N.getOperand(0);
2492 }
else if (
N.getOpcode() ==
ISD::OR) {
2494 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2506 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2507 Base =
N.getOperand(0);
2578 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2584 Base =
N.getOperand(0);
2587 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2589 assert(!cast<ConstantSDNode>(
N.getOperand(1).getOperand(1))->getZExtValue()
2590 &&
"Cannot handle constant offsets yet!");
2591 Disp =
N.getOperand(1).getOperand(0);
2596 Base =
N.getOperand(0);
2599 }
else if (
N.getOpcode() ==
ISD::OR) {
2602 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2612 dyn_cast<FrameIndexSDNode>(
N.getOperand(0))) {
2616 Base =
N.getOperand(0);
2629 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2632 CN->getValueType(0));
2637 if ((CN->getValueType(0) ==
MVT::i32 ||
2638 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2639 (!EncodingAlignment ||
2640 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2641 int Addr = (int)CN->getZExtValue();
2682 Base =
N.getOperand(0);
2698 Base =
N.getOperand(0);
2731 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2732 Base =
N.getOperand(0);
2745 Ty *PCRelCand = dyn_cast<Ty>(
N);
2757 if (isValidPCRelNode<ConstantPoolSDNode>(
N) ||
2758 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
2759 isValidPCRelNode<JumpTableSDNode>(
N) ||
2760 isValidPCRelNode<BlockAddressSDNode>(
N))
2776 EVT MemVT =
LD->getMemoryVT();
2783 if (!
ST.hasP8Vector())
2788 if (!
ST.hasP9Vector())
2801 if (UI.getUse().get().getResNo() == 0 &&
2823 Ptr =
LD->getBasePtr();
2824 VT =
LD->getMemoryVT();
2825 Alignment =
LD->getAlignment();
2827 Ptr =
ST->getBasePtr();
2828 VT =
ST->getMemoryVT();
2829 Alignment =
ST->getAlignment();
2852 if (isa<FrameIndexSDNode>(Base) || isa<RegisterSDNode>(Base))
2855 SDValue Val = cast<StoreSDNode>(
N)->getValue();
2885 isa<ConstantSDNode>(
Offset))
2900 unsigned &HiOpFlags,
unsigned &LoOpFlags,
2942 const bool Is64Bit = Subtarget.
isPPC64();
2957 EVT PtrVT =
Op.getValueType();
2973 return getTOCEntry(DAG,
SDLoc(
CP), GA);
2976 unsigned MOHiFlag, MOLoFlag;
2983 return getTOCEntry(DAG,
SDLoc(
CP), GA);
3043 EVT PtrVT =
Op.getValueType();
3061 return getTOCEntry(DAG,
SDLoc(
JT), GA);
3064 unsigned MOHiFlag, MOLoFlag;
3071 return getTOCEntry(DAG,
SDLoc(GA), GA);
3081 EVT PtrVT =
Op.getValueType();
3100 return getTOCEntry(DAG,
SDLoc(BASDN), GA);
3109 unsigned MOHiFlag, MOLoFlag;
3130 bool is64bit = Subtarget.
isPPC64();
3178 if (!
TM.isPositionIndependent())
3237 PtrVT, GOTPtr, TGA, TGA);
3239 PtrVT, TLSAddr, TGA);
3248 EVT PtrVT =
Op.getValueType();
3274 return getTOCEntry(DAG,
DL, GA);
3277 unsigned MOHiFlag, MOLoFlag;
3285 return getTOCEntry(DAG,
DL, GA);
3331 if (
C->isAllOnesValue() ||
C->isNullValue())
3340 EVT LHSVT =
Op.getOperand(0).getValueType();
3342 EVT VT =
Op.getValueType();
3352 EVT VT = Node->getValueType(0);
3354 SDValue InChain = Node->getOperand(0);
3355 SDValue VAListPtr = Node->getOperand(1);
3356 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
3397 InChain = OverflowArea.
getValue(1);
3443 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3450 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3465 return Op.getOperand(0);
3474 "Expecting Inline ASM node.");
3483 unsigned NumOps =
Op.getNumOperands();
3484 if (
Op.getOperand(NumOps - 1).getValueType() ==
MVT::Glue)
3489 unsigned Flags = cast<ConstantSDNode>(
Op.getOperand(i))->getZExtValue();
3504 for (; NumVals; --NumVals, ++i) {
3505 Register Reg = cast<RegisterSDNode>(
Op.getOperand(i))->getReg();
3506 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3531 bool isPPC64 = (PtrVT ==
MVT::i64);
3535 TargetLowering::ArgListEntry Entry;
3537 Entry.Ty = IntPtrTy;
3538 Entry.Node = Trmp;
Args.push_back(Entry);
3541 Entry.Node = DAG.
getConstant(isPPC64 ? 48 : 40, dl,
3543 Args.push_back(Entry);
3545 Entry.Node = FPtr;
Args.push_back(Entry);
3546 Entry.Node = Nest;
Args.push_back(Entry);
3550 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3554 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3555 return CallResult.second;
3569 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
3570 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3605 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3608 uint64_t
StackOffset = PtrVT.getSizeInBits()/8 - 1;
3611 uint64_t FPROffset = 1;
3614 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
3620 uint64_t nextOffset = FPROffset;
3629 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
3632 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
3634 nextOffset += FrameOffset;
3635 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
3638 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
3644 static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
3645 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
3646 PPC::F11, PPC::F12, PPC::F13};
3651 unsigned PtrByteSize) {
3659 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
3668 unsigned PtrByteSize) {
3669 Align Alignment(PtrByteSize);
3676 Alignment =
Align(16);
3681 if (BVAlign > PtrByteSize) {
3682 if (BVAlign.value() % PtrByteSize != 0)
3684 "ByVal alignment is not a multiple of the pointer size");
3686 Alignment = BVAlign;
3709 unsigned PtrByteSize,
unsigned LinkageSize,
3710 unsigned ParamAreaSize,
unsigned &ArgOffset,
3711 unsigned &AvailableFPRs,
3712 unsigned &AvailableVRs) {
3713 bool UseMemory =
false;
3718 ArgOffset =
alignTo(ArgOffset, Alignment);
3721 if (ArgOffset >= LinkageSize + ParamAreaSize)
3727 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
3730 if (ArgOffset > LinkageSize + ParamAreaSize)
3737 if (AvailableFPRs > 0) {
3745 if (AvailableVRs > 0) {
3757 unsigned NumBytes) {
3761 SDValue PPCTargetLowering::LowerFormalArguments(
3766 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg,
Ins, dl, DAG,
3769 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg,
Ins, dl, DAG,
3772 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg,
Ins, dl, DAG,
3776 SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
3818 const Align PtrAlign(4);
3827 CCInfo.AllocateStack(LinkageSize, PtrAlign);
3829 CCInfo.PreAnalyzeFormalArguments(
Ins);
3832 CCInfo.clearWasPPCF128();
3834 for (
unsigned i = 0,
e = ArgLocs.
size(); i !=
e; ++i) {
3847 RC = &PPC::GPRCRegClass;
3851 RC = &PPC::VSSRCRegClass;
3852 else if (Subtarget.
hasSPE())
3853 RC = &PPC::GPRCRegClass;
3855 RC = &PPC::F4RCRegClass;
3859 RC = &PPC::VSFRCRegClass;
3860 else if (Subtarget.
hasSPE())
3862 RC = &PPC::GPRCRegClass;
3864 RC = &PPC::F8RCRegClass;
3869 RC = &PPC::VRRCRegClass;
3872 RC = &PPC::VRRCRegClass;
3876 RC = &PPC::VRRCRegClass;
3884 assert(i + 1 <
e &&
"No second half of double precision argument");
3886 unsigned RegHi = MF.
addLiveIn(ArgLocs[++i].getLocReg(), RC);
3912 ArgOffset += ArgSize - ObjSize;
3930 CCByValInfo.AllocateStack(CCInfo.getNextStackOffset(), PtrAlign);
3935 unsigned MinReservedArea = CCByValInfo.getNextStackOffset();
3936 MinReservedArea =
std::max(MinReservedArea, LinkageSize);
3953 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
3958 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
3970 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
3975 CCInfo.getNextStackOffset(),
true));
3984 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
3988 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
4003 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4007 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4020 if (!MemOps.
empty())
4031 const SDLoc &dl)
const {
4042 SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4055 "fastcc not supported on varargs functions");
4061 unsigned PtrByteSize = 8;
4065 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4066 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4070 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4083 bool HasParameterArea = !isELFv2ABI || isVarArg;
4084 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4085 unsigned NumBytes = LinkageSize;
4086 unsigned AvailableFPRs = Num_FPR_Regs;
4087 unsigned AvailableVRs = Num_VR_Regs;
4088 for (
unsigned i = 0,
e =
Ins.size(); i !=
e; ++i) {
4093 PtrByteSize, LinkageSize, ParamAreaSize,
4094 NumBytes, AvailableFPRs, AvailableVRs))
4095 HasParameterArea =
true;
4102 unsigned ArgOffset = LinkageSize;
4103 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4106 unsigned CurArgIdx = 0;
4107 for (
unsigned ArgNo = 0,
e =
Ins.size(); ArgNo !=
e; ++ArgNo) {
4109 bool needsLoad =
false;
4110 EVT ObjectVT =
Ins[ArgNo].VT;
4111 EVT OrigVT =
Ins[ArgNo].ArgVT;
4113 unsigned ArgSize = ObjSize;
4115 if (
Ins[ArgNo].isOrigArg()) {
4116 std::advance(FuncArg,
Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4117 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4122 unsigned CurArgOffset;
4124 auto ComputeArgOffset = [&]() {
4128 ArgOffset =
alignTo(ArgOffset, Alignment);
4129 CurArgOffset = ArgOffset;
4136 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4137 GPR_idx =
std::min(GPR_idx, Num_GPR_Regs);
4143 assert(
Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4150 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4172 if (HasParameterArea ||
4173 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4180 if (ObjSize < PtrByteSize) {
4184 if (!isLittleEndian) {
4190 if (GPR_idx != Num_GPR_Regs) {
4191 unsigned VReg = MF.
addLiveIn(GPR[GPR_idx++], &PPC::G8RCRegClass);
4196 if (ObjSize==1 || ObjSize==2 || ObjSize==4) {
4213 ArgOffset += PtrByteSize;
4222 for (
unsigned j = 0; j < ArgSize; j += PtrByteSize) {
4223 if (GPR_idx == Num_GPR_Regs)
4226 unsigned VReg = MF.
addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass);
4239 ArgOffset += ArgSize;
4250 unsigned VReg = MF.
addLiveIn(PPC::X11, &PPC::G8RCRegClass);
4254 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4262 if (GPR_idx != Num_GPR_Regs) {
4263 unsigned VReg = MF.
addLiveIn(GPR[GPR_idx++], &PPC::G8RCRegClass);
4270 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4276 ArgSize = PtrByteSize;
4287 if (FPR_idx != Num_FPR_Regs) {
4293 ? &PPC::VSSRCRegClass
4294 : &PPC::F4RCRegClass);
4297 ? &PPC::VSFRCRegClass
4298 : &PPC::F8RCRegClass);
4309 unsigned VReg = MF.
addLiveIn(GPR[GPR_idx++], &PPC::G8RCRegClass);
4314 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4333 ArgOffset += ArgSize;
4335 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4349 if (VR_idx != Num_VR_Regs) {
4350 unsigned VReg = MF.
addLiveIn(VR[VR_idx], &PPC::VRRCRegClass);
4366 if (ObjSize < ArgSize && !isLittleEndian)
4367 CurArgOffset += ArgSize - ObjSize;
4377 unsigned MinReservedArea;
4378 if (HasParameterArea)
4379 MinReservedArea =
std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4381 MinReservedArea = LinkageSize;
4398 int Depth = ArgOffset;
4407 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4408 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4409 unsigned VReg = MF.
addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass);
4420 if (!MemOps.
empty())
4429 unsigned ParamSize) {
4431 if (!isTailCall)
return 0;
4435 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4437 if (SPDiff < FI->getTailCallSPDelta())
4452 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4468 if (!
TM.shouldAssumeDSOLocal(*Caller->getParent(), GV))
4474 const Function *
F = dyn_cast<Function>(GV);
4475 const GlobalAlias *Alias = dyn_cast<GlobalAlias>(GV);
4480 F = dyn_cast<Function>(GlobalObj);
4513 if (
TM.getFunctionSections() || GV->
hasComdat() || Caller->hasComdat() ||
4516 if (
const auto *
F = dyn_cast<Function>(GV)) {
4517 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4529 const unsigned PtrByteSize = 8;
4533 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4534 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4538 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4542 const unsigned NumFPRs = 13;
4544 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4546 unsigned NumBytes = LinkageSize;
4547 unsigned AvailableFPRs = NumFPRs;
4548 unsigned AvailableVRs = NumVRs;
4551 if (Param.Flags.isNest())
continue;
4554 LinkageSize, ParamAreaSize, NumBytes,
4555 AvailableFPRs, AvailableVRs))
4566 auto CalleeArgEnd = CB.
arg_end();
4569 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4570 const Value* CalleeArg = *CalleeArgIter;
4571 const Value* CallerArg = &(*CallerArgIter);
4572 if (CalleeArg == CallerArg)
4580 isa<UndefValue>(CalleeArg))
4598 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4608 bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4614 if (
DisableSCO && !TailCallOpt)
return false;
4617 if (isVarArg)
return false;
4649 if (
Caller.getCallingConv() != CalleeCC &&
4696 PPCTargetLowering::IsEligibleForTailCallOptimization(
SDValue Callee,
4712 for (
unsigned i = 0; i !=
Ins.size(); i++) {
4714 if (Flags.
isByVal())
return false;
4724 return G->getGlobal()->hasHiddenVisibility()
4725 ||
G->getGlobal()->hasProtectedVisibility();
4735 if (!
C)
return nullptr;
4737 int Addr =
C->getZExtValue();
4738 if ((
Addr & 3) != 0 ||
4744 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
4751 struct TailCallArgumentInfo {
4756 TailCallArgumentInfo() =
default;
4766 for (
unsigned i = 0,
e = TailCallArgs.
size(); i !=
e; ++i) {
4768 SDValue FIN = TailCallArgs[i].FrameIdxOp;
4769 int FI = TailCallArgs[i].FrameIdx;
4772 Chain, dl,
Arg, FIN,
4781 int SPDiff,
const SDLoc &dl) {
4787 bool isPPC64 = Subtarget.
isPPC64();
4788 int SlotSize = isPPC64 ? 8 : 4;
4789 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
4791 NewRetAddrLoc,
true);
4794 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
4806 int Offset = ArgOffset + SPDiff;
4807 uint32_t OpSize = (
Arg.getValueSizeInBits() + 7) / 8;
4811 TailCallArgumentInfo
Info;
4813 Info.FrameIdxOp = FIN;
4821 SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
4827 LROpOut = getReturnAddrFrameIndex(DAG);
4844 return DAG.
getMemcpy(Chain, dl, Dst, Src, SizeNode,
4853 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
4876 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
4886 if (!MemOpChains2.
empty())
4906 return G->getGlobal()->getValueType()->isFunctionTy();
4912 SDValue PPCTargetLowering::LowerCallResult(
4920 CCRetInfo.AnalyzeCallResult(
4926 for (
unsigned i = 0,
e = RVLocs.
size(); i !=
e; ++i) {
4935 Chain =
Lo.getValue(1);
4936 InFlag =
Lo.getValue(2);
4940 Chain =
Hi.getValue(1);
4941 InFlag =
Hi.getValue(2);
5052 auto isLocalCallee = [&]() {
5058 !dyn_cast_or_null<GlobalIFunc>(GV);
5069 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5083 assert(!isa<GlobalIFunc>(GV) &&
"IFunc is not supported on AIX.");
5084 return getAIXFuncEntryPointSymbolSDNode(GV);
5091 const char *SymName = S->getSymbol();
5097 dyn_cast_or_null<Function>(
Mod->getNamedValue(SymName)))
5098 return getAIXFuncEntryPointSymbolSDNode(
F);
5104 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5112 SymName = getExternalFunctionEntryPointSymbol(SymName)->
getName().
data();
5125 "Expected a CALLSEQ_STARTSDNode.");
5200 const unsigned Alignment = Subtarget.
isPPC64() ? 8 : 4;
5204 Alignment, MMOFlags);
5211 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5218 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5230 "Nest parameter is not supported on AIX.");
5246 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5249 const bool IsPPC64 = Subtarget.
isPPC64();
5298 for (
unsigned i = 0,
e = RegsToPass.size(); i !=
e; ++i)
5300 RegsToPass[i].second.getValueType()));
5317 assert(
Mask &&
"Missing call preserved mask for calling convention");
5325 SDValue PPCTargetLowering::FinishCall(
5340 if (!CFlags.IsIndirect)
5344 dl, CFlags.HasNest, Subtarget);
5354 if (CFlags.IsTailCall) {
5358 cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) ||
5361 isa<ConstantSDNode>(Callee) ||
5363 "Expecting a global address, external symbol, absolute value, "
5364 "register or an indirect tail call when PC Relative calls are "
5368 "Unexpected call opcode for a tail call.");
5374 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5391 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg,
Ins, dl,
5415 isTailCall = IsEligibleForTailCallOptimization_64SVR4(
5416 Callee, CallConv, CB, isVarArg, Outs,
Ins, DAG);
5418 isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv, isVarArg,
5432 isa<GlobalAddressSDNode>(Callee)) &&
5433 "Callee should be an llvm::Function object.");
5436 <<
"\nTCO callee: ");
5443 "site marked musttail");
5448 if (Subtarget.
useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
5450 Callee = LowerGlobalAddress(Callee, DAG);
5453 CallConv, isTailCall, isVarArg, isPatchPoint,
5461 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals,
Ins, dl, DAG,
5466 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals,
Ins, dl, DAG,
5468 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals,
Ins, dl, DAG,
5472 SDValue PPCTargetLowering::LowerCall_32SVR4(
5483 const bool IsVarArg = CFlags.IsVarArg;
5484 const bool IsTailCall = CFlags.IsTailCall;
5490 const Align PtrAlign(4);
5515 CCInfo.PreAnalyzeCallOperands(Outs);
5521 unsigned NumArgs = Outs.
size();
5523 for (
unsigned i = 0; i != NumArgs; ++i) {
5524 MVT ArgVT = Outs[i].VT;
5528 if (Outs[i].IsFixed) {
5538 errs() <<
"Call operand #" << i <<
" has unhandled type "
5548 CCInfo.clearWasPPCF128();
5555 CCByValInfo.AllocateStack(CCInfo.getNextStackOffset(), PtrAlign);
5562 unsigned NumBytes = CCByValInfo.getNextStackOffset();
5576 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
5587 bool seenFloatArg =
false;
5592 for (
unsigned i = 0, RealArgIdx = 0, j = 0,
e = ArgLocs.
size();
5594 ++i, ++RealArgIdx) {
5604 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
5627 Chain = CallSeqStart = NewCallSeqStart;
5653 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
5677 if (!MemOpChains.
empty())
5683 for (
unsigned i = 0,
e = RegsToPass.
size(); i !=
e; ++i) {
5684 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
5685 RegsToPass[i].second, InFlag);
5693 SDValue Ops[] = { Chain, InFlag };
5705 return FinishCall(CFlags, dl, DAG, RegsToPass, InFlag, Chain, CallSeqStart,
5706 Callee, SPDiff, NumBytes,
Ins, InVals, CB);
5711 SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
5723 return NewCallSeqStart;
5726 SDValue PPCTargetLowering::LowerCall_64SVR4(
5735 unsigned NumOps = Outs.
size();
5736 bool IsSibCall =
false;
5740 unsigned PtrByteSize = 8;
5744 if (CFlags.IsTailCall && !
getTargetMachine().Options.GuaranteedTailCallOpt)
5755 assert(!(IsFastCall && CFlags.IsVarArg) &&
5756 "fastcc not supported on varargs functions");
5763 unsigned NumBytes = LinkageSize;
5764 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
5767 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
5768 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
5772 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
5783 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
5784 if (!HasParameterArea) {
5785 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
5786 unsigned AvailableFPRs = NumFPRs;
5787 unsigned AvailableVRs = NumVRs;
5788 unsigned NumBytesTmp = NumBytes;
5789 for (
unsigned i = 0; i != NumOps; ++i) {
5790 if (Outs[i].Flags.
isNest())
continue;
5792 PtrByteSize, LinkageSize, ParamAreaSize,
5793 NumBytesTmp, AvailableFPRs, AvailableVRs))
5794 HasParameterArea =
true;
5800 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
5805 HasParameterArea =
false;
5808 for (
unsigned i = 0; i != NumOps; ++i) {
5810 EVT ArgVT = Outs[i].VT;
5811 EVT OrigVT = Outs[i].ArgVT;
5819 if (NumGPRsUsed > NumGPRs)
5820 HasParameterArea =
true;
5827 if (++NumGPRsUsed <= NumGPRs)
5837 if (++NumVRsUsed <= NumVRs)
5841 if (++NumVRsUsed <= NumVRs)
5846 if (++NumFPRsUsed <= NumFPRs)
5850 HasParameterArea =
true;
5857 NumBytes =
alignTo(NumBytes, Alignement);
5861 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
5864 unsigned NumBytesActuallyUsed = NumBytes;
5874 if (HasParameterArea)
5875 NumBytes =
std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
5877 NumBytes = LinkageSize;
5892 if (CFlags.IsTailCall)
5904 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
5915 unsigned ArgOffset = LinkageSize;
5921 for (
unsigned i = 0; i != NumOps; ++i) {
5924 EVT ArgVT = Outs[i].VT;
5925 EVT OrigVT = Outs[i].ArgVT;
5934 auto ComputePtrOff = [&]() {
5938 ArgOffset =
alignTo(ArgOffset, Alignment);
5949 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
5950 GPR_idx =
std::min(GPR_idx, NumGPRs);
5982 if (GPR_idx != NumGPRs) {
5988 ArgOffset += PtrByteSize;
5993 if (GPR_idx == NumGPRs &&
Size < 8) {
5995 if (!isLittleEndian) {
6000 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, AddPtr,
6003 ArgOffset += PtrByteSize;
6020 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, PtrOff,
6025 if (
Size < 8 && GPR_idx != NumGPRs) {
6035 if (!isLittleEndian) {
6039 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, AddPtr,
6050 ArgOffset += PtrByteSize;
6056 for (
unsigned j=0; j<
Size; j+=PtrByteSize) {
6059 if (GPR_idx != NumGPRs) {
6064 ArgOffset += PtrByteSize;
6066 ArgOffset += ((
Size - j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6073 switch (
Arg.getSimpleValueType().SimpleTy) {
6087 if (GPR_idx != NumGPRs) {
6088 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++],
Arg));
6093 assert(HasParameterArea &&
6094 "Parameter area must exist to pass an argument in memory.");
6096 true, CFlags.IsTailCall,
false, MemOpChains,
6097 TailCallArguments, dl);
6099 ArgOffset += PtrByteSize;
6102 ArgOffset += PtrByteSize;
6115 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6116 bool NeededLoad =
false;
6119 if (FPR_idx != NumFPRs)
6123 if (!NeedGPROrStack)
6125 else if (GPR_idx != NumGPRs && !IsFastCall) {
6145 }
else if (ArgOffset % PtrByteSize != 0) {
6149 if (!isLittleEndian)
6157 if (!isLittleEndian)
6167 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6180 assert(HasParameterArea &&
6181 "Parameter area must exist to pass an argument in memory.");
6183 true, CFlags.IsTailCall,
false, MemOpChains,
6184 TailCallArguments, dl);
6191 if (!IsFastCall || NeededLoad) {
6195 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6215 if (CFlags.IsVarArg) {
6216 assert(HasParameterArea &&
6217 "Parameter area must exist if we have a varargs call.");
6223 if (VR_idx != NumVRs) {
6230 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6231 if (GPR_idx == NumGPRs)
6244 if (VR_idx != NumVRs) {
6245 RegsToPass.
push_back(std::make_pair(VR[VR_idx++],
Arg));
6250 assert(HasParameterArea &&
6251 "Parameter area must exist to pass an argument in memory.");
6253 true, CFlags.IsTailCall,
true, MemOpChains,
6254 TailCallArguments, dl);
6265 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6266 "mismatch in size of parameter area");
6267 (void)NumBytesActuallyUsed;
6269 if (!MemOpChains.
empty())
6275 if (CFlags.IsIndirect) {
6279 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6294 if (isELFv2ABI && !CFlags.IsPatchPoint)
6295 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6301 for (
unsigned i = 0,
e = RegsToPass.
size(); i !=
e; ++i) {
6302 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6303 RegsToPass[i].second, InFlag);
6307 if (CFlags.IsTailCall && !IsSibCall)
6311 return FinishCall(CFlags, dl, DAG, RegsToPass, InFlag, Chain, CallSeqStart,
6312 Callee, SPDiff, NumBytes,
Ins, InVals, CB);
6321 const bool IsPPC64 = Subtarget.
isPPC64();
6338 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6340 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6341 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6345 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6346 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6351 "register width are not supported.");
6357 if (ByValSize == 0) {
6364 const unsigned StackSize =
alignTo(ByValSize, PtrAlign);
6386 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6393 LocInfo = ArgFlags.
isSExt() ? CCValAssign::LocInfo::SExt
6394 : CCValAssign::LocInfo::ZExt;
6415 for (
unsigned I = 0;
I < StoreSize;
I += PtrAlign.
value()) {
6416 if (
unsigned Reg = State.
AllocateReg(IsPPC64 ? GPR_64 : GPR_32)) {
6417 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6452 "variadic arguments for vector types are unimplemented for AIX");
6458 "passing vector parameters to the stack is unimplemented for AIX");
6469 "i64 should have been split for 32-bit codegen.");
6477 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
6479 return &PPC::F4RCRegClass;
6481 return &PPC::F8RCRegClass;
6489 return &PPC::VRRCRegClass;
6514 "Reg must be a valid argument register!");
6515 return LASize + 4 * (
Reg - PPC::R3);
6520 "Reg must be a valid argument register!");
6521 return LASize + 8 * (
Reg - PPC::X3);
6567 SDValue PPCTargetLowering::LowerFormalArguments_AIX(
6574 "Unexpected calling convention!");
6585 const bool IsPPC64 = Subtarget.
isPPC64();
6586 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
6598 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
6599 CCInfo.AnalyzeFormalArguments(
Ins,
CC_AIX);
6603 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
6609 "passing vector parameters to the stack is unimplemented for AIX");
6630 const unsigned Size =
6660 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
6662 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
6664 const unsigned VReg = MF.
addLiveIn(PhysReg, RegClass);
6675 CopyFrom.
getValue(1), dl, CopyFrom,
6685 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
6688 "RegLocs should be for ByVal argument.");
6695 if (
Offset != StackSize) {
6697 "Expected MemLoc for remaining bytes.");
6698 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
6724 assert((ValSize <= LocSize) &&
6725 "Object size is larger than size of MemLoc");
6728 if (LocSize > ValSize)
6729 CurArgOffset += LocSize - ValSize;
6731 const bool IsImmutable =
6744 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
6746 unsigned CallerReservedArea =
6747 std::max(CCInfo.getNextStackOffset(), LinkageSize + MinParameterSaveArea);
6753 CallerReservedArea =
6763 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6765 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6766 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6767 const unsigned NumGPArgRegs =
array_lengthof(IsPPC64 ? GPR_64 : GPR_32);
6772 for (
unsigned GPRIndex =
6773 (CCInfo.getNextStackOffset() - LinkageSize) / PtrByteSize;
6774 GPRIndex < NumGPArgRegs; ++GPRIndex) {
6776 const unsigned VReg =
6777 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
6778 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
6790 if (!MemOps.
empty())
6796 SDValue PPCTargetLowering::LowerCall_AIX(
6809 "Unexpected calling convention!");
6811 if (CFlags.IsPatchPoint)
6819 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
6827 const bool IsPPC64 = Subtarget.
isPPC64();
6829 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
6830 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
6831 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
6839 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
6840 const unsigned NumBytes =
std::max(LinkageSize + MinParameterSaveAreaSize,
6841 CCInfo.getNextStackOffset());
6857 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
6858 const unsigned ValNo = ArgLocs[
I].getValNo();
6871 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
6880 unsigned LoadOffset = 0;
6883 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
6886 LoadOffset += PtrByteSize;
6889 "Unexpected location for pass-by-value argument.");
6893 if (LoadOffset == ByValSize)
6897 assert(ArgLocs[
I].getValNo() == ValNo &&
6898 "Expected additional location for by-value argument.");
6900 if (ArgLocs[
I].isMemLoc()) {
6901 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
6906 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
6912 CallSeqStart, MemcpyFlags, DAG, dl);
6921 const unsigned ResidueBytes = ByValSize % PtrByteSize;
6922 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
6923 "Unexpected register residue for by-value argument.");
6925 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
6939 "Unexpected load emitted during handling of pass-by-value "
6947 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
6963 "passing vector parameters to the stack is unimplemented for AIX");
6997 "Unexpected register handling for calling convention.");
7006 else if (
Arg.getValueType().getFixedSizeInBits() <
7015 "Unexpected custom register for argument!");
7036 if (!MemOpChains.
empty())
7041 if (CFlags.IsIndirect) {
7042 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7046 const unsigned TOCSaveOffset =
7062 for (
auto Reg : RegsToPass) {
7067 const int SPDiff = 0;
7068 return FinishCall(CFlags, dl, DAG, RegsToPass, InFlag, Chain, CallSeqStart,
7069 Callee, SPDiff, NumBytes,
Ins, InVals, CB);
7079 return CCInfo.CheckReturn(
7094 CCInfo.AnalyzeReturn(Outs,
7103 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7145 RetOps.push_back(
Flag);
7151 PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7156 EVT IntVT =
Op.getValueType();
7160 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7162 SDValue Ops[2] = {Chain, FPSIdx};
7176 bool isPPC64 = Subtarget.
isPPC64();
7177 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7197 bool isPPC64 = Subtarget.
isPPC64();
7218 PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7220 bool isPPC64 = Subtarget.
isPPC64();
7254 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7255 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
7266 bool isPPC64 = Subtarget.
isPPC64();
7278 Op.getOperand(0),
Op.getOperand(1));
7285 Op.getOperand(0),
Op.getOperand(1));
7289 if (
Op.getValueType().isVector())
7290 return LowerVectorLoad(
Op, DAG);
7293 "Custom lowering only for i1 loads");
7314 if (
Op.getOperand(1).getValueType().isVector())
7315 return LowerVectorStore(
Op, DAG);
7318 "Custom lowering only for i1 stores");
7338 "Custom lowering only for i1 results");
7366 EVT TrgVT =
Op.getValueType();
7378 if (SrcSize > 256 ||
7390 if (SrcSize == 256) {
7401 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
7409 for (
unsigned i = 0; i < TrgNumElts; ++i)
7412 for (
unsigned i = 1; i <= TrgNumElts; ++i)
7416 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
7429 if (!
Op.getOperand(0).getValueType().isFloatingPoint() ||
7430 !
Op.getOperand(2).getValueType().isFloatingPoint() || Subtarget.
hasSPE())
7435 EVT ResVT =
Op.getValueType();
7436 EVT CmpVT =
Op.getOperand(0).getValueType();
7437 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
7438 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
7444 if (Subtarget.
hasP9Vector() && LHS == TV && RHS == FV) {
7572 bool IsStrict =
Op->isStrictFPOpcode();
7581 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
7595 switch (
Op.getSimpleValueType().SimpleTy) {
7603 "i64 FP_TO_UINT is supported only with FPCVT");
7609 {Chain, Src}, Flags);
7616 void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
7618 const SDLoc &dl)
const {
7622 bool IsStrict =
Op->isStrictFPOpcode();
7626 (IsSigned || Subtarget.
hasFPCVT());
7628 int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
7637 Alignment =
Align(4);
7640 SDValue Ops[] = { Chain, Tmp, FIPtr };
7644 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
7648 if (
Op.getValueType() ==
MVT::i32 && !i32Stack) {
7657 RLI.Alignment = Alignment;
7665 const SDLoc &dl)
const {
7668 if (
Op->isStrictFPOpcode())
7675 const SDLoc &dl)
const {
7676 bool IsStrict =
Op->isStrictFPOpcode();
7679 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
7681 EVT DstVT =
Op.getValueType();
7708 {Op.getOperand(0), Lo, Hi}, Flags);
7711 {Res.getValue(1), Res}, Flags);
7717 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
7741 {Chain, Src, FltOfs}, Flags);
7745 {Chain, Val}, Flags);
7748 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
7767 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
7770 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
7772 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
7773 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
7784 bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
7789 if (
Op->isStrictFPOpcode())
7798 Op.getOperand(0).getValueType())) {
7800 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
7805 if (!
LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
7806 LD->isNonTemporal())
7808 if (
LD->getMemoryVT() != MemVT)
7818 RLI.Ptr =
LD->getBasePtr();
7819 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
7821 "Non-pre-inc AM on PPC?");
7826 RLI.Chain =
LD->getChain();
7827 RLI.MPI =
LD->getPointerInfo();
7828 RLI.IsDereferenceable =
LD->isDereferenceable();
7829 RLI.IsInvariant =
LD->isInvariant();
7830 RLI.Alignment =
LD->getAlign();
7831 RLI.AAInfo =
LD->getAAInfo();
7832 RLI.Ranges =
LD->getRanges();
7834 RLI.ResChain =
SDValue(
LD,
LD->isIndexed() ? 2 : 1);
7842 void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
7848 SDLoc dl(NewResChain);
7853 "A new TF really is required here");
7862 bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
7863 SDNode *Origin =
Op.getOperand(0).getNode();
7878 if (UI.getUse().get().getResNo() != 0)
7908 if (
Op->isStrictFPOpcode()) {
7910 Chain =
Op.getOperand(0);
7914 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
7922 const SDLoc &dl)
const {
7925 "Invalid floating point type as target of conversion");
7927 "Int to FP conversions with direct moves require FPCVT");
7928 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
7951 for (
unsigned i = 1; i < NumConcat; ++i)
7958 const SDLoc &dl)
const {
7959 bool IsStrict =
Op->isStrictFPOpcode();
7960 unsigned Opc =
Op.getOpcode();
7961 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
7964 "Unexpected conversion type");
7966 "Supports conversions to v2f64/v4f32 only.");
7981 for (
unsigned i = 0; i < WideNumElts; ++i)
7984 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
7985 int SaveElts = FourEltRes ? 4 : 2;
7987 for (
int i = 0; i < SaveElts; i++)
7988 ShuffV[i * Stride] = i;
7990 for (
int i = 1; i <= SaveElts; i++)
7991 ShuffV[i * Stride - 1] = i - 1;
7999 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8012 {Op.getOperand(0), Extend}, Flags);
8014 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8022 bool IsStrict =
Op->isStrictFPOpcode();
8023 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8031 EVT OutVT =
Op.getValueType();
8034 return LowerINT_TO_FPVector(
Op, DAG, dl);
8058 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8061 "UINT_TO_FP is supported only with FPCVT");
8117 if (canReuseLoadAddress(SINT,
MVT::i64, RLI, DAG)) {
8119 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8120 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8125 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8126 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8130 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8135 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8136 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8140 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8158 "Expected an i32 store");
8164 RLI.Alignment =
Align(4);
8168 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8169 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8174 Chain =
Bits.getValue(1);
8180 Chain =
FP.getValue(1);
8186 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8195 "Unhandled INT_TO_FP type in custom expander!");
8208 if (!(ReusingLoad = canReuseLoadAddress(Src,
MVT::i32, RLI, DAG))) {
8218 "Expected an i32 store");
8224 RLI.Alignment =
Align(4);
8229 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8230 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8236 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
8239 "i32->FP without LFIWAX supported only on PPC64");
8248 Chain, dl, Ext64, FIdx,
8262 Chain =
FP.getValue(1);
8267 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8298 EVT VT =
Op.getValueType();
8304 Chain =
MFFS.getValue(1);
8318 "Stack slot adjustment is valid only on big endian subtargets!");
8348 EVT VT =
Op.getValueType();
8352 VT ==
Op.getOperand(1).getValueType() &&
8372 SDValue OutOps[] = { OutLo, OutHi };
8377 EVT VT =
Op.getValueType();
8381 VT ==
Op.getOperand(1).getValueType() &&
8401 SDValue OutOps[] = { OutLo, OutHi };
8407 EVT VT =
Op.getValueType();
8410 VT ==
Op.getOperand(1).getValueType() &&
8430 SDValue OutOps[] = { OutLo, OutHi };
8437 EVT VT =
Op.getValueType();
8444 EVT AmtVT =
Z.getValueType();
8467 static const MVT VTys[] = {
8474 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
8479 EVT CanonicalVT = VTys[SplatSize-1];
8523 for (
unsigned i = 0; i != 16; ++i)
8551 bool IsSplat =
true;
8552 bool IsLoad =
false;
8579 return !(IsSplat && IsLoad);
8617 APFloat APFloatToConvert = ArgAPFloat;
8618 bool LosesInfo =
true;
8623 ArgAPFloat = APFloatToConvert;
8650 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
8653 APInt APSplatBits, APSplatUndef;
8654 unsigned SplatBitSize;
8656 bool BVNIsConstantSplat =
8664 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
8703 if (!BVNIsConstantSplat || SplatBitSize > 32) {
8705 bool IsPermutedLoad =
false;
8714 unsigned ElementSize =
LD->getMemoryVT().getScalarSizeInBits();
8719 unsigned NumUsesOfInputLD = 128 / ElementSize;
8721 if (BVInOp.isUndef())
8723 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
8725 ((Subtarget.
hasVSX() && ElementSize == 64) ||
8726 (Subtarget.
hasP9Vector() && ElementSize == 32))) {
8734 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8755 unsigned SplatSize = SplatBitSize / 8;
8760 if (SplatBits == 0) {
8776 Op.getValueType(), DAG, dl);
8788 int32_t SextVal= (int32_t(SplatBits << (32-SplatBitSize)) >>
8790 if (SextVal >= -16 && SextVal <= 15)
8803 if (SextVal >= -32 && SextVal <= 31) {
8812 if (VT ==
Op.getValueType())
8821 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
8835 static const signed char SplatCsts[] = {
8836 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
8837 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
8843 int i = SplatCsts[idx];
8847 unsigned TypeShiftAmt = i & (SplatBitSize-1);
8850 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
8852 static const unsigned IIDs[] = {
8853 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
8854 Intrinsic::ppc_altivec_vslw
8861 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
8863 static const unsigned IIDs[] = {
8864 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
8865 Intrinsic::ppc_altivec_vsrw
8872 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
8873 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
8875 static const unsigned IIDs[] = {
8876 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
8877 Intrinsic::ppc_altivec_vrlw
8884 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
8890 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
8896 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
8911 unsigned OpNum = (PFEntry >> 26) & 0x0F;
8912 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
8913 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
8929 if (LHSID == (1*9+2)*9+3)
return LHS;
8930 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
8942 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
8943 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
8944 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
8945 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
8948 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
8949 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
8950 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
8951 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
8954 for (
unsigned i = 0; i != 16; ++i)
8955 ShufIdxs[i] = (i&3)+0;
8958 for (
unsigned i = 0; i != 16; ++i)
8959 ShufIdxs[i] = (i&3)+4;
8962 for (
unsigned i = 0; i != 16; ++i)
8963 ShufIdxs[i] = (i&3)+8;
8966 for (
unsigned i = 0; i != 16; ++i)
8967 ShufIdxs[i] = (i&3)+12;
8988 const unsigned BytesInVector = 16;
8993 unsigned ShiftElts = 0, InsertAtByte = 0;
8997 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
8998 0, 15, 14, 13, 12, 11, 10, 9};
8999 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
9000 1, 2, 3, 4, 5, 6, 7, 8};
9003 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
9015 bool FoundCandidate =
false;
9019 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
9022 for (
unsigned i = 0; i < BytesInVector; ++i) {
9023 unsigned CurrentElement =
Mask[i];
9026 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
9029 bool OtherElementsInOrder =
true;
9032 for (
unsigned j = 0; j < BytesInVector; ++j) {
9039 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
9040 if (
Mask[j] != OriginalOrder[j] + MaskOffset) {
9041 OtherElementsInOrder =
false;
9048 if (OtherElementsInOrder) {
9055 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
9056 : BigEndianShifts[CurrentElement & 0xF];
9057 Swap = CurrentElement < BytesInVector;
9059 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
9060 FoundCandidate =
true;
9065 if (!FoundCandidate)
9089 const unsigned NumHalfWords = 8;
9090 const unsigned BytesInVector = NumHalfWords * 2;
9099 unsigned ShiftElts = 0, InsertAtByte = 0;
9103 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
9104 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
9107 uint32_t OriginalOrderLow = 0x1234567;
9108 uint32_t OriginalOrderHigh = 0x89ABCDEF;
9111 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9112 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9113 Mask |= ((
uint32_t)(
N->getMaskElt(i * 2) / 2) << MaskShift);
9129 bool FoundCandidate =
false;
9132 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9133 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9135 uint32_t MaskOtherElts = ~(0xF << MaskShift);
9143 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
9144 TargetOrder = OriginalOrderLow;
9148 if (MaskOneElt == VINSERTHSrcElem &&
9149 (
Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9150 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9151 FoundCandidate =
true;
9157 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
9159 if ((
Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9161 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
9162 : BigEndianShifts[MaskOneElt & 0x7];
9163 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9164 Swap = MaskOneElt < NumHalfWords;
9165 FoundCandidate =
true;
9171 if (!FoundCandidate)
9206 auto ShuffleMask = SVN->
getMask();
9218 ShuffleMask = cast<ShuffleVectorSDNode>(
VecShuffle)->getMask();
9227 APInt APSplatValue, APSplatUndef;
9228 unsigned SplatBitSize;
9244 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
9245 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
9246 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
9248 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
9249 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
9250 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
9258 for (; SplatBitSize < 32; SplatBitSize <<= 1)
9259 SplatVal |= (SplatVal << SplatBitSize);
9274 "Only set v1i128 as custom, other type shouldn't reach here!");
9279 if (SHLAmt % 8 == 0) {
9281 std::iota(
Mask.begin(),
Mask.end(), 0);
9311 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
9312 if (!isa<ShuffleVectorSDNode>(NewShuffle))
9315 SVOp = cast<ShuffleVectorSDNode>(
Op);
9316 V1 =
Op.getOperand(0);
9317 V2 =
Op.getOperand(1);
9319 EVT VT =
Op.getValueType();
9322 unsigned ShiftElts, InsertAtByte;
9328 bool IsPermutedLoad =
false;
9330 if (InputLoad && Subtarget.
hasVSX() &&
V2.isUndef() &&
9340 if (IsPermutedLoad) {
9341 assert(isLittleEndian &&
"Unexpected permuted load on big endian target");
9342 SplatIdx += IsFourByte ? 2 : 1;
9343 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
9344 "Splat of a value outside of the loaded memory");
9349 if ((IsFourByte && Subtarget.
hasP9Vector()) || !IsFourByte) {
9352 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
9354 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
9369 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
9397 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
9398 return SplatInsertNode;
9403 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
9406 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
9410 if (Subtarget.
hasVSX() &&
9423 if (Subtarget.
hasVSX() &&
9456 if (Subtarget.
hasVSX()) {
9501 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
9521 unsigned PFIndexes[4];
9522 bool isFourElementShuffle =
true;
9523 for (
unsigned i = 0; i != 4 && isFourElementShuffle; ++i) {
9525 for (
unsigned j = 0; j != 4; ++j) {
9526 if (PermMask[i*4+j] < 0)
9529 unsigned ByteSource = PermMask[i*4+j];
9530 if ((ByteSource & 3) != j) {
9531 isFourElementShuffle =
false;
9536 EltNo = ByteSource/4;
9537 }
else if (EltNo != ByteSource/4) {
9538 isFourElementShuffle =
false;
9542 PFIndexes[i] = EltNo;
9550 if (isFourElementShuffle && !isLittleEndian) {
9552 unsigned PFTableIndex =
9553 PFIndexes[0]*9*9*9+PFIndexes[1]*9*9+PFIndexes[2]*9+PFIndexes[3];
9556 unsigned Cost = (PFEntry >> 30);
9575 if (
V2.isUndef())
V2 = V1;
9589 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
9591 for (
unsigned j = 0; j != BytesPerElement; ++j)
9600 ShufflesHandledWithVPERM++;
9602 LLVM_DEBUG(
dbgs() <<
"Emitting a VPERM for the following shuffle:\n");
9604 LLVM_DEBUG(
dbgs() <<
"With the following permute control vector:\n");
9620 unsigned IntrinsicID =
9621 cast<ConstantSDNode>(Intrin.
getOperand(0))->getZExtValue();
9624 switch (IntrinsicID) {
9628 case Intrinsic::ppc_altivec_vcmpbfp_p:
9632 case Intrinsic::ppc_altivec_vcmpeqfp_p:
9636 case Intrinsic::ppc_altivec_vcmpequb_p:
9640 case Intrinsic::ppc_altivec_vcmpequh_p:
9644 case Intrinsic::ppc_altivec_vcmpequw_p:
9648 case Intrinsic::ppc_altivec_vcmpequd_p:
9655 case Intrinsic::ppc_altivec_vcmpneb_p:
9656 case Intrinsic::ppc_altivec_vcmpneh_p:
9657 case Intrinsic::ppc_altivec_vcmpnew_p:
9658 case Intrinsic::ppc_altivec_vcmpnezb_p:
9659 case Intrinsic::ppc_altivec_vcmpnezh_p:
9660 case Intrinsic::ppc_altivec_vcmpnezw_p:
9662 switch (IntrinsicID) {
9665 case Intrinsic::ppc_altivec_vcmpneb_p:
9668 case Intrinsic::ppc_altivec_vcmpneh_p:
9671 case Intrinsic::ppc_altivec_vcmpnew_p:
9674 case Intrinsic::ppc_altivec_vcmpnezb_p:
9677 case Intrinsic::ppc_altivec_vcmpnezh_p:
9680 case Intrinsic::ppc_altivec_vcmpnezw_p:
9688 case Intrinsic::ppc_altivec_vcmpgefp_p:
9692 case Intrinsic::ppc_altivec_vcmpgtfp_p:
9696 case Intrinsic::ppc_altivec_vcmpgtsb_p:
9700 case Intrinsic::ppc_altivec_vcmpgtsh_p:
9704 case Intrinsic::ppc_altivec_vcmpgtsw_p:
9708 case Intrinsic::ppc_altivec_vcmpgtsd_p:
9715 case Intrinsic::ppc_altivec_vcmpgtub_p:
9719 case Intrinsic::ppc_altivec_vcmpgtuh_p:
9723 case Intrinsic::ppc_altivec_vcmpgtuw_p:
9727 case Intrinsic::ppc_altivec_vcmpgtud_p:
9735 case Intrinsic::ppc_altivec_vcmpequq:
9736 case Intrinsic::ppc_altivec_vcmpgtsq:
9737 case Intrinsic::ppc_altivec_vcmpgtuq:
9740 switch (IntrinsicID) {
9743 case Intrinsic::ppc_altivec_vcmpequq:
9746 case Intrinsic::ppc_altivec_vcmpgtsq:
9749 case Intrinsic::ppc_altivec_vcmpgtuq:
9756 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
9757 case Intrinsic::ppc_vsx_xvcmpgedp_p:
9758 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
9759 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
9760 case Intrinsic::ppc_vsx_xvcmpgesp_p:
9761 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
9762 if (Subtarget.
hasVSX()) {
9763 switch (IntrinsicID) {
9764 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
9767 case Intrinsic::ppc_vsx_xvcmpgedp_p:
9770 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
9773 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
9776 case Intrinsic::ppc_vsx_xvcmpgesp_p:
9779 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
9789 case Intrinsic::ppc_altivec_vcmpbfp:
9792 case Intrinsic::ppc_altivec_vcmpeqfp:
9795 case Intrinsic::ppc_altivec_vcmpequb:
9798 case Intrinsic::ppc_altivec_vcmpequh:
9801 case Intrinsic::ppc_altivec_vcmpequw:
9804 case Intrinsic::ppc_altivec_vcmpequd:
9810 case Intrinsic::ppc_altivec_vcmpneb:
9811 case Intrinsic::ppc_altivec_vcmpneh:
9812 case Intrinsic::ppc_altivec_vcmpnew:
9813 case Intrinsic::ppc_altivec_vcmpnezb:
9814 case Intrinsic::ppc_altivec_vcmpnezh:
9815 case Intrinsic::ppc_altivec_vcmpnezw:
9817 switch (IntrinsicID) {
9820 case Intrinsic::ppc_altivec_vcmpneb:
9823 case Intrinsic::ppc_altivec_vcmpneh:
9826 case Intrinsic::ppc_altivec_vcmpnew:
9829 case Intrinsic::ppc_altivec_vcmpnezb:
9832 case Intrinsic::ppc_altivec_vcmpnezh:
9835 case Intrinsic::ppc_altivec_vcmpnezw:
9842 case Intrinsic::ppc_altivec_vcmpgefp:
9845 case Intrinsic::ppc_altivec_vcmpgtfp:
9848 case Intrinsic::ppc_altivec_vcmpgtsb:
9851 case Intrinsic::ppc_altivec_vcmpgtsh:
9854 case Intrinsic::ppc_altivec_vcmpgtsw:
9857 case Intrinsic::ppc_altivec_vcmpgtsd:
9863 case Intrinsic::ppc_altivec_vcmpgtub:
9866 case Intrinsic::ppc_altivec_vcmpgtuh:
9869 case Intrinsic::ppc_altivec_vcmpgtuw:
9872 case Intrinsic::ppc_altivec_vcmpgtud:
9878 case Intrinsic::ppc_altivec_vcmpequq_p:
9879 case Intrinsic::ppc_altivec_vcmpgtsq_p:
9880 case Intrinsic::ppc_altivec_vcmpgtuq_p:
9883 switch (IntrinsicID) {
9886 case Intrinsic::ppc_altivec_vcmpequq_p:
9889 case Intrinsic::ppc_altivec_vcmpgtsq_p:
9892 case Intrinsic::ppc_altivec_vcmpgtuq_p:
9906 unsigned IntrinsicID =
9907 cast<ConstantSDNode>(
Op.getOperand(0))->getZExtValue();
9911 switch (IntrinsicID) {
9912 case Intrinsic::thread_pointer:
9918 case Intrinsic::ppc_mma_disassemble_acc:
9919 case Intrinsic::ppc_vsx_disassemble_pair: {
9922 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
9927 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
9949 Op.getOperand(1),
Op.getOperand(2),
9972 switch (cast<ConstantSDNode>(
Op.getOperand(1))->getZExtValue()) {
9975 BitNo = 0; InvertBit =
false;
9978 BitNo = 0; InvertBit =
true;
9981 BitNo = 2; InvertBit =
false;
9984 BitNo = 2; InvertBit =
true;
10006 int ArgStart = isa<ConstantSDNode>(
Op.getOperand(0)) ? 0 : 1;
10008 switch (cast<ConstantSDNode>(
Op.getOperand(ArgStart))->getZExtValue()) {
10009 case Intrinsic::ppc_cfence: {
10010 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
10011 assert(Subtarget.
isPPC64() &&
"Only 64-bit is supported for now.");
10014 Op.getOperand(ArgStart + 1)),
10033 int VectorIndex = 0;
10046 "Expecting an atomic compare-and-swap here.");
10048 auto *AtomicNode = cast<AtomicSDNode>(
Op.getNode());
10049 EVT MemVT = AtomicNode->getMemoryVT();
10067 for (
int i = 0,
e = AtomicNode->getNumOperands(); i <
e; i++)
10068 Ops.
push_back(AtomicNode->getOperand(i));
10096 "Should only be called for ISD::INSERT_VECTOR_ELT");
10103 EVT VT =
Op.getValueType();
10111 unsigned InsertAtElement =
C->getZExtValue();
10112 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
10114 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
10128 EVT VT =
Op.getValueType();
10137 "Type unsupported without MMA");
10139 "Type unsupported without paired vector support");
10144 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
10174 EVT StoreVT =
Value.getValueType();
10183 "Type unsupported without MMA");
10185 "Type unsupported without paired vector support");
10188 unsigned NumVecs = 2;
10193 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
10194 unsigned VecNum = Subtarget.
isLittleEndian() ? NumVecs - 1 - Idx : Idx;
10198 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
10213 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
10238 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
10256 for (
unsigned i = 0; i != 8; ++i) {
10257 if (isLittleEndian) {
10259 Ops[i*2+1] = 2*i+16;
10262 Ops[i*2+1] = 2*i+1+16;
10265 if (isLittleEndian)
10275 bool IsStrict =
Op->isStrictFPOpcode();
10276 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() ==
MVT::f128 &&
10287 "Should only be called for ISD::FP_EXTEND");
10304 "Node should have 2 operands with second one being a constant!");
10310 int Idx = cast<ConstantSDNode>(Op0.
getOperand(1))->getZExtValue();
10316 int DWord = Idx >> 1;
10336 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
10339 LD->getMemoryVT(),
LD->getMemOperand());
10349 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
10352 LD->getMemoryVT(),
LD->getMemOperand());
10363 switch (
Op.getOpcode()) {
10384 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
10410 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
10411 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
10423 return LowerFP_ROUND(
Op, DAG);
10436 return LowerINTRINSIC_VOID(
Op, DAG);
10438 return LowerBSWAP(
Op, DAG);
10440 return LowerATOMIC_CMP_SWAP(
Op, DAG);
10448 switch (
N->getOpcode()) {
10450 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
10461 if (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue() !=
10462 Intrinsic::loop_decrement)
10466 "Unexpected result type for CTR decrement intrinsic");
10468 N->getValueType(0));
10481 EVT VT =
N->getValueType(0);
10496 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
10502 if (!
N->getValueType(0).isVector())
10529 Module *M =
Builder.GetInsertBlock()->getParent()->getParent();
10531 return Builder.CreateCall(Func, {});
10553 if (isa<LoadInst>(Inst) && Subtarget.
isPPC64())
10556 Builder.GetInsertBlock()->getParent()->getParent(),
10557 Intrinsic::ppc_cfence, {Inst->getType()}),
10567 unsigned AtomicSize,
10568 unsigned BinOpcode,
10569 unsigned CmpOpcode,
10570 unsigned CmpPred)
const {
10574 auto LoadMnemonic = PPC::LDARX;
10575 auto StoreMnemonic = PPC::STDCX;
10576 switch (AtomicSize) {
10580 LoadMnemonic = PPC::LBARX;
10581 StoreMnemonic = PPC::STBCX;
10585 LoadMnemonic = PPC::LHARX;
10586 StoreMnemonic = PPC::STHCX;
10590 LoadMnemonic = PPC::LWARX;
10591 StoreMnemonic = PPC::STWCX;
10594 LoadMnemonic = PPC::LDARX;
10595 StoreMnemonic = PPC::STDCX;
10611 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
10613 F->insert(It, loopMBB);
10615 F->insert(It, loop2MBB);
10616 F->insert(It, exitMBB);
10622 Register TmpReg = (!BinOpcode) ? incr :
10624 : &PPC::GPRCRegClass);
10649 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
10655 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
10657 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
10659 BuildMI(BB, dl,
TII->get(CmpOpcode), PPC::CR0)
10662 BuildMI(BB, dl,
TII->get(CmpOpcode), PPC::CR0)
10685 switch(
MI.getOpcode()) {
10689 return TII->isSignExtended(
MI);
10713 case PPC::EXTSB8_32_64:
10714 case PPC::EXTSB8_rec:
10715 case PPC::EXTSB_rec:
10718 case PPC::EXTSH8_32_64:
10719 case PPC::EXTSH8_rec:
10720 case PPC::EXTSH_rec:
10723 case PPC::EXTSWSLI_32_64:
10724 case PPC::EXTSWSLI_32_64_rec:
10725 case PPC::EXTSWSLI_rec:
10726 case PPC::EXTSW_32:
10727 case PPC::EXTSW_32_64:
10728 case PPC::EXTSW_32_64_rec:
10729 case PPC::EXTSW_rec:
10732 case PPC::SRAWI_rec:
10733 case PPC::SRAW_rec:
10742 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
10755 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
10757 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
10758 .
addReg(
MI.getOperand(3).getReg());
10759 MI.getOperand(3).setReg(ValueReg);
10770 bool is64bit = Subtarget.
isPPC64();
10772 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
10783 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
10785 F->insert(It, loopMBB);
10787 F->insert(It, loop2MBB);
10788 F->insert(It, exitMBB);
10794 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
10837 if (ptrA != ZeroReg) {
10839 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
10847 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
10848 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
10851 .
addImm(is8bit ? 28 : 27);
10852 if (!isLittleEndian)
10853 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
10855 .
addImm(is8bit ? 24 : 16);
10857 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
10862 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
10872 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
10876 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
10881 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
10885 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
10888 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
10899 unsigned ValueReg = SReg;
10900 unsigned CmpReg = Incr2Reg;
10901 if (CmpOpcode == PPC::CMPW) {
10903 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
10907 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
10909 ValueReg = ValueSReg;
10912 BuildMI(BB, dl,
TII->get(CmpOpcode), PPC::CR0)
10957 Register DstReg =
MI.getOperand(0).getReg();
10960 Register mainDstReg =
MRI.createVirtualRegister(RC);
10961 Register restoreDstReg =
MRI.createVirtualRegister(RC);
10965 "Invalid Pointer Size!");
11013 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
11014 Register BufReg =
MI.getOperand(1).getReg();
11029 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
11031 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
11034 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
11057 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
11078 TII->get(PPC::PHI), DstReg)
11082 MI.eraseFromParent();
11097 "Invalid Pointer Size!");
11100 (PVT ==
MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
11103 unsigned FP = (PVT ==
MVT::i64) ? PPC::X31 : PPC::R31;
11104 unsigned SP = (PVT ==
MVT::i64) ? PPC::X1 : PPC::R1;
11118 Register BufReg =
MI.getOperand(0).getReg();
11184 MI.eraseFromParent();
11200 "Unexpected stack alignment");
11203 unsigned StackProbeSize = 4096;
11211 return StackProbeSize ? StackProbeSize :
StackAlign;
11223 const bool isPPC64 = Subtarget.
isPPC64();
11255 MF->
insert(MBBIter, TestMBB);
11256 MF->
insert(MBBIter, BlockMBB);
11257 MF->
insert(MBBIter, TailMBB);
11262 Register DstReg =
MI.getOperand(0).getReg();
11263 Register NegSizeReg =
MI.getOperand(1).getReg();
11264 Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
11265 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
11266 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
11267 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
11273 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
11275 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
11281 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
11282 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
11284 .
addDef(ActualNegSizeReg)
11286 .
add(
MI.getOperand(2))
11287 .
add(
MI.getOperand(3));
11293 .
addReg(ActualNegSizeReg);
11296 int64_t NegProbeSize = -(int64_t)ProbeSize;
11298 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
11300 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
11302 .
addImm(NegProbeSize >> 16);
11306 .
addImm(NegProbeSize & 0xFFFF);
11313 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
11315 .
addReg(ActualNegSizeReg)
11317 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
11321 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
11324 .
addReg(ActualNegSizeReg);
11333 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
11334 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
11348 BuildMI(BlockMBB,
DL,
TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
11359 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
11362 MaxCallFrameSizeReg)
11363 .
add(
MI.getOperand(2))
11364 .
add(
MI.getOperand(3));
11365 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
11367 .
addReg(MaxCallFrameSizeReg);
11376 MI.eraseFromParent();
11378 ++NumDynamicAllocaProbed;
11385 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
11386 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
11388 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
11401 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
11402 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
11404 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
11405 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
11418 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
11419 MI.getOpcode() == PPC::SELECT_CC_I8 ||
MI.getOpcode() == PPC::SELECT_I4 ||
11420 MI.getOpcode() == PPC::SELECT_I8) {
11422 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
11423 MI.getOpcode() == PPC::SELECT_CC_I8)
11424 Cond.push_back(
MI.getOperand(4));
11427 Cond.push_back(
MI.getOperand(1));
11430 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
11431 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
11432 }
else if (
MI.getOpcode() == PPC::SELECT_CC_F4 ||
11433 MI.getOpcode() == PPC::SELECT_CC_F8 ||
11434 MI.getOpcode() == PPC::SELECT_CC_F16 ||
11435 MI.getOpcode() == PPC::SELECT_CC_VRRC ||
11436 MI.getOpcode() == PPC::SELECT_CC_VSFRC ||
11437 MI.getOpcode() == PPC::SELECT_CC_VSSRC ||
11438 MI.getOpcode() == PPC::SELECT_CC_VSRC ||
11439 MI.getOpcode() == PPC::SELECT_CC_SPE4 ||
11440 MI.getOpcode() == PPC::SELECT_CC_SPE ||
11441 MI.getOpcode() == PPC::SELECT_F4 ||
11442 MI.getOpcode() == PPC::SELECT_F8 ||
11443 MI.getOpcode() == PPC::SELECT_F16 ||
11444 MI.getOpcode() == PPC::SELECT_SPE ||
11445 MI.getOpcode() == PPC::SELECT_SPE4 ||
11446 MI.getOpcode() == PPC::SELECT_VRRC ||
11447 MI.getOpcode() == PPC::SELECT_VSFRC ||
11448 MI.getOpcode() == PPC::SELECT_VSSRC ||
11449 MI.getOpcode() == PPC::SELECT_VSRC) {
11464 F->insert(It, copy0MBB);
11465 F->insert(It, sinkMBB);
11476 if (
MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8 ||
11477 MI.getOpcode() == PPC::SELECT_F4 ||
MI.getOpcode() == PPC::SELECT_F8 ||
11478 MI.getOpcode() == PPC::SELECT_F16 ||
11479 MI.getOpcode() == PPC::SELECT_SPE4 ||
11480 MI.getOpcode() == PPC::SELECT_SPE ||
11481 MI.getOpcode() == PPC::SELECT_VRRC ||
11482 MI.getOpcode() == PPC::SELECT_VSFRC ||
11483 MI.getOpcode() == PPC::SELECT_VSSRC ||
11484 MI.getOpcode() == PPC::SELECT_VSRC) {
11486 .
addReg(
MI.getOperand(1).getReg())
11489 unsigned SelectPred =
MI.getOperand(4).getImm();
11492 .
addReg(
MI.getOperand(1).getReg())
11509 .
addReg(
MI.getOperand(3).getReg())
11511 .
addReg(
MI.getOperand(2).getReg())
11513 }
else if (
MI.getOpcode() == PPC::ReadTB) {
11529 F->insert(It, readMBB);
11530 F->insert(It, sinkMBB);
11551 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
11561 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
11563 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
11565 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
11567 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
11570 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
11572 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
11574 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
11576 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
11579 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
11581 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
11583 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
11585 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
11588 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
11590 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
11592 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
11594 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
11597 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
11599 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
11601 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
11603 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
11606 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
11608 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
11610 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
11612 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
11615 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
11617 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
11619 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
11621 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
11624 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
11626 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
11628 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
11630 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
11633 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
11635 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
11637 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
11639 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
11642 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
11644 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
11646 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
11648 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
11651 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
11653 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
11655 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
11657 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
11659 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
11660 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
11662 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
11664 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
11665 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
11667 auto LoadMnemonic = PPC::LDARX;
11668 auto StoreMnemonic = PPC::STDCX;
11669 switch (
MI.getOpcode()) {
11672 case PPC::ATOMIC_CMP_SWAP_I8:
11673 LoadMnemonic = PPC::LBARX;
11674 StoreMnemonic = PPC::STBCX;
11677 case PPC::ATOMIC_CMP_SWAP_I16:
11678 LoadMnemonic = PPC::LHARX;
11679 StoreMnemonic = PPC::STHCX;
11682 case PPC::ATOMIC_CMP_SWAP_I32:
11683 LoadMnemonic = PPC::LWARX;
11684 StoreMnemonic = PPC::STWCX;
11686 case PPC::ATOMIC_CMP_SWAP_I64:
11687 LoadMnemonic = PPC::LDARX;
11688 StoreMnemonic = PPC::STDCX;
11694 Register oldval =
MI.getOperand(3).getReg();
11695 Register newval =
MI.getOperand(4).getReg();
11702 F->insert(It, loop1MBB);
11703 F->insert(It, loop2MBB);
11704 F->insert(It, midMBB);
11705 F->insert(It, exitMBB);
11728 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), PPC::CR0)
11761 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
11762 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
11766 bool is64bit = Subtarget.
isPPC64();
11768 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
11773 Register oldval =
MI.getOperand(3).getReg();
11774 Register newval =
MI.getOperand(4).getReg();
11781 F->insert(It, loop1MBB);
11782 F->insert(It, loop2MBB);
11783 F->insert(It, midMBB);
11784 F->insert(It, exitMBB);
11791 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
11810 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
11843 if (ptrA != ZeroReg) {
11845 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
11854 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
11855 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
11858 .
addImm(is8bit ? 28 : 27);
11859 if (!isLittleEndian)
11860 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
11862 .
addImm(is8bit ? 24 : 16);
11864 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
11869 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
11874 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
11877 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
11884 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
11888 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
11899 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
11905 BuildMI(BB, dl,
TII->get(PPC::CMPW), PPC::CR0)
11916 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
11947 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
11982 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
11983 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
11984 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
11985 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
11989 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
11993 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
11997 .
addReg(
MI.getOperand(1).getReg())
12000 MI.getOperand(0).getReg())
12001 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
12002 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
12008 MI.getOperand(0).getReg())
12010 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
12012 unsigned Imm =
MI.getOperand(1).getImm();
12015 MI.getOperand(0).getReg())
12017 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
12019 Register OldFPSCRReg =
MI.getOperand(0).getReg();
12033 unsigned Mode =
MI.getOperand(1).getImm();
12041 }
else if (
MI.getOpcode() == PPC::SETRND) {
12049 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
12051 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
12055 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
12058 if (RC == &PPC::F8RCRegClass) {
12061 "Unsupported RegClass.");
12063 StoreOp = PPC::STFD;
12068 (RegInfo.
getRegClass(DestReg) == &PPC::F8RCRegClass) &&
12069 "Unsupported RegClass.");
12102 Register OldFPSCRReg =
MI.getOperand(0).getReg();
12119 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
12127 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
12128 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
12134 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
12141 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
12150 }
else if (
MI.getOpcode() == PPC::SETFLM) {
12154 Register OldFPSCRReg =
MI.getOperand(0).getReg();
12158 Register NewFPSCRReg =
MI.getOperand(1).getReg();
12164 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
12165 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
12171 MI.eraseFromParent();
12184 int RefinementSteps = Subtarget.
hasRecipPrec() ? 1 : 3;
12187 return RefinementSteps;
12193 EVT VT =
Op.getValueType();
12220 PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
12223 EVT VT =
Op.getValueType();
12232 int Enabled,
int &RefinementSteps,
12233 bool &UseOneConstNR,
12234 bool Reciprocal)
const {
12240 if (RefinementSteps == ReciprocalEstimate::Unspecified)
12253 int &RefinementSteps)
const {
12259 if (RefinementSteps == ReciprocalEstimate::Unspecified)
12266 unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
12304 unsigned Bytes,
int Dist,
12314 int FI = cast<FrameIndexSDNode>(Loc)->getIndex();
12315 int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
12318 if (
FS != BFS ||
FS != (
int)Bytes)
return false;
12322 SDValue Base1 = Loc, Base2 = BaseLoc;
12323 int64_t Offset1 = 0, Offset2 = 0;
12326 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
12336 if (isGA1 && isGA2 && GV1 == GV2)
12337 return Offset1 == (Offset2 + Dist*Bytes);
12344 unsigned Bytes,
int Dist,
12347 EVT VT =
LS->getMemoryVT();
12354 switch (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue()) {
12355 default:
return false;
12356 case Intrinsic::ppc_altivec_lvx:
12357 case Intrinsic::ppc_altivec_lvxl:
12358 case Intrinsic::ppc_vsx_lxvw4x:
12359 case Intrinsic::ppc_vsx_lxvw4x_be:
12362 case Intrinsic::ppc_vsx_lxvd2x:
12363 case Intrinsic::ppc_vsx_lxvd2x_be:
12366 case Intrinsic::ppc_altivec_lvebx:
12369 case Intrinsic::ppc_altivec_lvehx:
12372 case Intrinsic::ppc_altivec_lvewx:
12382 switch (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue()) {
12383 default:
return false;
12384 case Intrinsic::ppc_altivec_stvx:
12385 case Intrinsic::ppc_altivec_stvxl:
12386 case Intrinsic::ppc_vsx_stxvw4x:
12389 case Intrinsic::ppc_vsx_stxvd2x:
12392 case Intrinsic::ppc_vsx_stxvw4x_be:
12395 case Intrinsic::ppc_vsx_stxvd2x_be:
12398 case Intrinsic::ppc_altivec_stvebx:
12401 case Intrinsic::ppc_altivec_stvehx:
12404 case Intrinsic::ppc_altivec_stvewx:
12422 EVT VT =
LD->getMemoryVT();
12431 while (!Queue.empty()) {
12432 SDNode *ChainNext = Queue.pop_back_val();
12433 if (!Visited.
insert(ChainNext).second)
12436 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
12440 if (!Visited.
count(ChainLD->getChain().getNode()))
12441 Queue.push_back(ChainLD->getChain().getNode());
12443 for (
const SDUse &
O : ChainNext->
ops())
12444 if (!Visited.
count(
O.getNode()))
12445 Queue.push_back(
O.getNode());
12447 LoadRoots.
insert(ChainNext);
12460 Queue.push_back(*
I);
12462 while (!Queue.empty()) {
12463 SDNode *LoadRoot = Queue.pop_back_val();
12464 if (!Visited.
insert(LoadRoot).second)
12467 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
12472 UE = LoadRoot->
use_end(); UI != UE; ++UI)
12473 if (((isa<MemSDNode>(*UI) &&
12474 cast<MemSDNode>(*UI)->getChain().getNode() == LoadRoot) ||
12476 Queue.push_back(*UI);
12509 auto Final = Shifted;
12520 DAGCombinerInfo &DCI)
const {
12528 if (!DCI.isAfterLegalizeDAG())
12534 UE =
N->use_end(); UI != UE; ++UI) {
12539 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(2))->get();
12540 auto OpSize =
N->getOperand(0).getValueSizeInBits();
12544 if (OpSize <
Size) {
12562 DAGCombinerInfo &DCI)
const {
12580 if (
N->getOperand(0).getValueType() !=
MVT::i32 &&
12581 N->getOperand(0).getValueType() !=
MVT::i64)
12589 cast<CondCodeSDNode>(
N->getOperand(
12591 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
12602 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
12625 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
12626 N->getOperand(0).getOpcode() !=
ISD::OR &&
12627 N->getOperand(0).getOpcode() !=
ISD::XOR &&
12637 N->getOperand(1).getOpcode() !=
ISD::AND &&
12638 N->getOperand(1).getOpcode() !=
ISD::OR &&
12639 N->getOperand(1).getOpcode() !=
ISD::XOR &&
12652 for (
unsigned i = 0; i < 2; ++i) {
12656 N->getOperand(i).getOperand(0).getValueType() ==
MVT::i1) ||
12657 isa<ConstantSDNode>(
N->getOperand(i)))
12668 while (!BinOps.
empty()) {
12676 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
12710 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
12711 if (isa<ConstantSDNode>(Inputs[i]))
12715 UE = Inputs[i].getNode()->use_end();
12737 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
12739 UE = PromOps[i].getNode()->use_end();
12762 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
12765 if (isa<ConstantSDNode>(Inputs[i]))
12771 std::list<HandleSDNode> PromOpHandles;
12772 for (
auto &PromOp : PromOps)
12773 PromOpHandles.emplace_back(PromOp);
12780 while (!PromOpHandles.empty()) {
12782 PromOpHandles.pop_back();
12788 if (!isa<ConstantSDNode>(PromOp.
getOperand(0)) &&
12791 PromOpHandles.emplace_front(PromOp);
12796 if (isa<ConstantSDNode>(RepValue))
12805 default:
C = 0;
break;
12810 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
12818 PromOpHandles.emplace_front(PromOp);
12826 for (
unsigned i = 0; i < 2; ++i)
12827 if (isa<ConstantSDNode>(Ops[
C+i]))
12836 return N->getOperand(0);
12844 DAGCombinerInfo &DCI)
const {
12870 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
12871 N->getOperand(0).getOpcode() !=
ISD::OR &&
12872 N->getOperand(0).getOpcode() !=
ISD::XOR &&
12883 while (!BinOps.
empty()) {
12891 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
12922 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
12923 if (isa<ConstantSDNode>(Inputs[i]))
12927 UE = Inputs[i].getNode()->use_end();
12937 SelectTruncOp[0].
insert(std::make_pair(
User,
12941 SelectTruncOp[0].
insert(std::make_pair(
User,
12944 SelectTruncOp[1].
insert(std::make_pair(
User,
12950 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
12952 UE = PromOps[i].getNode()->use_end();
12962 SelectTruncOp[0].
insert(std::make_pair(
User,
12966 SelectTruncOp[0].
insert(std::make_pair(
User,
12969 SelectTruncOp[1].
insert(std::make_pair(
User,
12975 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
12976 bool ReallyNeedsExt =
false;
12980 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
12981 if (isa<ConstantSDNode>(Inputs[i]))
12985 Inputs[i].getOperand(0).getValueSizeInBits();
12986 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
12991 OpBits-PromBits))) ||
12994 (OpBits-(PromBits-1)))) {
12995 ReallyNeedsExt =
true;
13003 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
13007 if (isa<ConstantSDNode>(Inputs[i]))
13010 SDValue InSrc = Inputs[i].getOperand(0);
13024 std::list<HandleSDNode> PromOpHandles;
13025 for (
auto &PromOp : PromOps)
13026 PromOpHandles.emplace_back(PromOp);
13032 while (!PromOpHandles.empty()) {
13034 PromOpHandles.pop_back();
13038 default:
C = 0;
break;
13043 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
13051 PromOpHandles.emplace_front(PromOp);
13061 (SelectTruncOp[1].count(PromOp.
getNode()) &&
13063 PromOpHandles.emplace_front(PromOp);
13072 for (
unsigned i = 0; i < 2; ++i) {
13073 if (!isa<ConstantSDNode>(Ops[
C+i]))
13090 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
13091 if (SI0 != SelectTruncOp[0].
end())
13093 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
13094 if (SI1 != SelectTruncOp[1].
end())
13103 if (!ReallyNeedsExt)
13104 return N->getOperand(0);
13111 N->getValueSizeInBits(0), PromBits),
13112 dl,
N->getValueType(0)));
13115 "Invalid extension type");
13118 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
13126 DAGCombinerInfo &DCI)
const {
13128 "Should be called with a SETCC node");
13130 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(2))->get();
13146 EVT VT =
N->getValueType(0);
13153 return DAGCombineTruncBoolExt(
N, DCI);
13172 combineElementTruncationToVectorTruncation(
SDNode *
N,
13173 DAGCombinerInfo &DCI)
const {
13175 "Should be called with a BUILD_VECTOR node");
13180 SDValue FirstInput =
N->getOperand(0);
13182 "The input operand must be an fp-to-int conversion.");
13191 bool IsSplat =
true;
13196 EVT TargetVT =
N->getValueType(0);
13197 for (
int i = 0,
e =
N->getNumOperands(); i <
e; ++i) {
13198 SDValue NextOp =
N->getOperand(i);
13202 if (NextConversion != FirstConversion)
13210 if (
N->getOperand(i) != FirstInput)
13221 for (
int i = 0,
e =
N->getNumOperands(); i <
e; ++i) {
13222 SDValue In =
N->getOperand(i).getOperand(0);
13247 return DAG.
getNode(Opcode, dl, TargetVT, BV);
13260 "Should be called with a BUILD_VECTOR node");
13265 if (!
N->getValueType(0).getVectorElementType().isByteSized())
13268 bool InputsAreConsecutiveLoads =
true;
13269 bool InputsAreReverseConsecutive =
true;
13270 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
13271 SDValue FirstInput =
N->getOperand(0);
13272 bool IsRoundOfExtLoad =
false;
13281 N->getNumOperands() == 1)
13284 for (
int i = 1,
e =
N->getNumOperands(); i <
e; ++i) {
13286 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
13289 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
13295 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
13296 LoadSDNode *LD1 = dyn_cast<LoadSDNode>(PreviousInput);
13297 LoadSDNode *LD2 = dyn_cast<LoadSDNode>(NextInput);
13304 InputsAreConsecutiveLoads =
false;
13306 InputsAreReverseConsecutive =
false;
13309 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
13313 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
13314 "The loads cannot be both consecutive and reverse consecutive.");
13317 IsRoundOfExtLoad ? FirstInput.
getOperand(0) : FirstInput;
13319 IsRoundOfExtLoad ?
N->getOperand(
N->getNumOperands()-1).getOperand(0) :
13320 N->getOperand(
N->getNumOperands()-1);
13322 LoadSDNode *LD1 = dyn_cast<LoadSDNode>(FirstLoadOp);
13324 if (InputsAreConsecutiveLoads) {
13325 assert(LD1 &&
"Input needs to be a LoadSDNode.");
13330 if (InputsAreReverseConsecutive) {
13331 assert(
LDL &&
"Input needs to be a LoadSDNode.");
13333 LDL->getBasePtr(),
LDL->getPointerInfo(),
13334 LDL->getAlignment());
13336 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
13340 DAG.
getUNDEF(
N->getValueType(0)), Ops);
13349 SDValue Input, uint64_t Elems,
13350 uint64_t CorrectElems) {
13359 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
13361 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
13363 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
13364 CorrectElems = CorrectElems >> 8;
13365 Elems = Elems >> 8;
13372 EVT VT =
N->getValueType(0);
13398 uint64_t TargetElems[] = {
13406 uint64_t Elems = 0;
13410 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
13430 if (Input && Input != Extract.
getOperand(0))
13436 Elems = Elems << 8;
13445 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
13446 if (!isSExtOfVecExtract(
N->getOperand(i))) {
13453 int TgtElemArrayIdx;
13455 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
13456 if (InputSize + OutputSize == 40)
13457 TgtElemArrayIdx = 0;
13458 else if (InputSize + OutputSize == 72)
13459 TgtElemArrayIdx = 1;
13460 else if (InputSize + OutputSize == 48)
13461 TgtElemArrayIdx = 2;
13462 else if (InputSize + OutputSize == 80)
13463 TgtElemArrayIdx = 3;
13464 else if (InputSize + OutputSize == 96)
13465 TgtElemArrayIdx = 4;
13469 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
13471 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
13472 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
13473 if (Elems != CorrectElems) {
13492 SDValue Operand =
N->getOperand(0);
13507 if (!ValidLDType ||
13513 LD->getChain(),
LD->getBasePtr(),
13522 DAGCombinerInfo &DCI)
const {
13524 "Should be called with a BUILD_VECTOR node");
13529 if (!Subtarget.
hasVSX())
13535 SDValue FirstInput =
N->getOperand(0);
13537 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
13552 if (Subtarget.
hasP9Altivec() && !DCI.isBeforeLegalize()) {
13578 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
13582 SDValue Ext2 =
N->getOperand(1).getOperand(0);
13589 if (!Ext1Op || !Ext2Op)
13598 if (FirstElem == 0 && SecondElem == 1)
13600 else if (FirstElem == 2 && SecondElem == 3)
13613 DAGCombinerInfo &DCI)
const {
13616 "Need an int -> FP conversion node here");
13629 if (!
Op.getOperand(0).getValueType().isSimple())
13631 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(
MVT::i1) ||
13632 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(
MVT::i64))
13635 SDValue FirstOperand(
Op.getOperand(0));
13636 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
13637 (FirstOperand.getValueType() ==
MVT::i8 ||
13638 FirstOperand.getValueType() ==
MVT::i16);
13641 bool DstDouble =
Op.getValueType() ==
MVT::f64;
13642 unsigned ConvOp =
Signed ?
13648 LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
13656 SDValue ExtOps[] = { Ld, WidthConst };
13668 if (
Op.getOperand(0).getValueType() ==
MVT::i32)
13672 "UINT_TO_FP is supported only with FPCVT");
13690 SDValue Src =
Op.getOperand(0).getOperand(0);
13693 DCI.AddToWorklist(Src.
getNode());
13709 DCI.AddToWorklist(
FP.getNode());
13728 switch (
N->getOpcode()) {
13733 Chain =
LD->getChain();
13734 Base =
LD->getBasePtr();
13735 MMO =
LD->getMemOperand();
13754 MVT VecTy =
N->getValueType(0).getSimpleVT();
13763 SDValue LoadOps[] = { Chain, Base };
13769 Chain =
Load.getValue(1);
13797 switch (
N->getOpcode()) {
13802 Chain =
ST->getChain();
13803 Base =
ST->getBasePtr();
13804 MMO =
ST->getMemOperand();
13824 SDValue Src =
N->getOperand(SrcOpnd);
13844 SDValue StoreOps[] = { Chain, Swap, Base };
13847 StoreOps, VecTy, MMO);
13854 DAGCombinerInfo &DCI)
const {
13858 unsigned Opcode =
N->getOperand(1).getOpcode();
13861 &&
"Not a FP_TO_INT Instruction!");
13863 SDValue Val =
N->getOperand(1).getOperand(0);
13864 EVT Op1VT =
N->getOperand(1).getValueType();
13871 bool ValidTypeForStoreFltAsInt =
13876 cast<StoreSDNode>(
N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
13882 DCI.AddToWorklist(Val.
getNode());
13890 Val = DAG.
getNode(ConvOpcode,
13892 DCI.AddToWorklist(Val.
getNode());
13896 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
13902 cast<StoreSDNode>(
N)->getMemoryVT(),
13903 cast<StoreSDNode>(
N)->getMemOperand());
13905 DCI.AddToWorklist(Val.
getNode());
13912 bool PrevElemFromFirstVec =
Mask[0] < NumElts;
13913 for (
int i = 1,
e =
Mask.size(); i <
e; i++) {
13914 if (PrevElemFromFirstVec &&
Mask[i] < NumElts)
13916 if (!PrevElemFromFirstVec &&
Mask[i] >= NumElts)
13918 PrevElemFromFirstVec = !PrevElemFromFirstVec;
13929 for (
int i = 0,
e =
Op.getNumOperands(); i <
e; i++) {
13930 FirstOp =
Op.getOperand(i);
13936 for (
int i = 1,
e =
Op.getNumOperands(); i <
e; i++)
13937 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
13947 Op =
Op.getOperand(0);
13954 int LHSMaxIdx,
int RHSMinIdx,
13955 int RHSMaxIdx,
int HalfVec) {
13956 for (
int i = 0,
e = ShuffV.
size(); i <
e; i++) {
13957 int Idx = ShuffV[i];
13958 if ((Idx >= 0 && Idx < LHSMaxIdx) || (Idx >= RHSMinIdx && Idx < RHSMaxIdx))
13959 ShuffV[i] += HalfVec;
13969 SDLoc dl(OrigSToV);
13972 "Expecting a SCALAR_TO_VECTOR here");
14020 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
14029 if (SToVLHS || SToVRHS) {
14032 int NumEltsOut = ShuffV.
size();
14036 int LHSMaxIdx = -1;
14037 int RHSMinIdx = -1;
14038 int RHSMaxIdx = -1;
14045 LHSMaxIdx = NumEltsOut / NumEltsIn;
14052 RHSMinIdx = NumEltsOut;
14053 RHSMaxIdx = NumEltsOut / NumEltsIn + RHSMinIdx;
14072 if (!isa<ShuffleVectorSDNode>(Res))
14074 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
14094 if (
Mask[0] < NumElts)
14095 for (
int i = 1,
e =
Mask.size(); i <
e; i += 2)
14096 ShuffV[i] = (ShuffV[i - 1] + NumElts);
14100 for (
int i = 0,
e =
Mask.size(); i <
e; i += 2)
14101 ShuffV[i] = (ShuffV[i + 1] + NumElts);
14105 SDValue SplatVal = cast<BuildVectorSDNode>(RHS.
getNode())->getSplatValue();
14114 DAGCombinerInfo &DCI)
const {
14116 "Not a reverse memop pattern!");
14121 auto I =
Mask.rbegin();
14122 auto E =
Mask.rend();
14124 for (;
I !=
E; ++
I) {
14144 if(!IsElementReverse(SVN))
14171 switch (
N->getOpcode()) {
14174 return combineADD(
N, DCI);
14176 return combineSHL(
N, DCI);
14178 return combineSRA(
N, DCI);
14180 return combineSRL(
N, DCI);
14182 return combineMUL(
N, DCI);
14185 return combineFMALike(
N, DCI);
14188 return N->getOperand(0);
14192 return N->getOperand(0);
14196 if (
C->isNullValue() ||
14197 C->isAllOnesValue())
14198 return N->getOperand(0);
14204 return DAGCombineExtBoolTrunc(
N, DCI);
14206 return combineTRUNCATE(
N, DCI);
14208 if (
SDValue CSCC = combineSetCC(
N, DCI))
14212 return DAGCombineTruncBoolExt(
N, DCI);
14215 return combineFPToIntToFP(
N, DCI);
14218 LSBaseSDNode* LSBase = cast<LSBaseSDNode>(
N->getOperand(0));
14219 return combineVReverseMemOP(cast<ShuffleVectorSDNode>(
N), LSBase, DCI);
14221 return combineVectorShuffle(cast<ShuffleVectorSDNode>(
N), DCI.
DAG);
14224 EVT Op1VT =
N->getOperand(1).getValueType();
14225 unsigned Opcode =
N->getOperand(1).getOpcode();
14228 SDValue Val= combineStoreFPToInt(
N, DCI);
14235 SDValue Val= combineVReverseMemOP(SVN, cast<LSBaseSDNode>(
N), DCI);
14241 if (cast<StoreSDNode>(
N)->isUnindexed() && Opcode ==
ISD::BSWAP &&
14242 N->getOperand(1).getNode()->hasOneUse() &&
14248 EVT mVT = cast<StoreSDNode>(
N)->getMemoryVT();
14252 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
14259 if (Op1VT.
bitsGT(mVT)) {
14269 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
14273 Ops, cast<StoreSDNode>(
N)->getMemoryVT(),
14274 cast<StoreSDNode>(
N)->getMemOperand());
14280 isa<ConstantSDNode>(
N->getOperand(1)) && Op1VT ==
MVT::i32) {
14282 EVT MemVT = cast<StoreSDNode>(
N)->getMemoryVT();
14292 cast<StoreSDNode>(
N)->setTruncatingStore(
true);
14309 EVT VT =
LD->getValueType(0);
14328 auto ReplaceTwoFloatLoad = [&]() {
14344 if (!
LD->hasNUsesOfValue(2, 0))
14347 auto UI =
LD->use_begin();
14348 while (UI.getUse().getResNo() != 0) ++UI;
14350 while (UI.getUse().getResNo() != 0) ++UI;
14351 SDNode *RightShift = *UI;
14359 if (RightShift->getOpcode() !=
ISD::SRL ||
14360 !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
14361 RightShift->getConstantOperandVal(1) != 32 ||
14362 !RightShift->hasOneUse())
14365 SDNode *Trunc2 = *RightShift->use_begin();
14388 if (
LD->isIndexed()) {
14390 "Non-pre-inc AM on PPC?");
14399 LD->getPointerInfo(),
LD->getAlignment(),
14400 MMOFlags,
LD->getAAInfo());
14406 LD->getPointerInfo().getWithOffset(4),
14407 MinAlign(
LD->getAlignment(), 4), MMOFlags,
LD->getAAInfo());
14409 if (
LD->isIndexed()) {
14423 if (ReplaceTwoFloatLoad())
14426 EVT MemVT =
LD->getMemoryVT();
14435 LD->getAlign() < ABIAlignment) {
14466 MVT PermCntlTy, PermTy, LDTy;
14467 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
14468 : Intrinsic::ppc_altivec_lvsl;
14469 IntrLD = Intrinsic::ppc_altivec_lvx;
14470 IntrPerm = Intrinsic::ppc_altivec_vperm;
14491 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
14495 BaseLoadOps, LDTy, BaseMMO);
14504 int IncValue = IncOffset;
14521 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
14525 ExtraLoadOps, LDTy, ExtraMMO);
14536 if (isLittleEndian)
14538 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
14541 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
14560 unsigned IID = cast<ConstantSDNode>(
N->getOperand(0))->getZExtValue();
14562 : Intrinsic::ppc_altivec_lvsl);
14563 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
14570 .
zext(Add.getScalarValueSizeInBits()))) {
14571 SDNode *BasePtr = Add->getOperand(0).getNode();
14573 UE = BasePtr->use_end();
14576 cast<ConstantSDNode>(UI->getOperand(0))->getZExtValue() ==
14587 if (isa<ConstantSDNode>(Add->getOperand(1))) {
14588 SDNode *BasePtr = Add->getOperand(0).getNode();
14590 UE = BasePtr->use_end(); UI != UE; ++UI) {
14591 if (UI->getOpcode() ==
ISD::ADD &&
14592 isa<ConstantSDNode>(UI->getOperand(1)) &&
14593 (cast<ConstantSDNode>(Add->getOperand(1))->getZExtValue() -
14594 cast<ConstantSDNode>(UI->getOperand(1))->getZExtValue()) %
14595 (1ULL <<
Bits) == 0) {
14600 cast<ConstantSDNode>(
VI->getOperand(0))->getZExtValue() == IID) {
14612 (IID == Intrinsic::ppc_altivec_vmaxsw ||
14613 IID == Intrinsic::ppc_altivec_vmaxsh ||
14614 IID == Intrinsic::ppc_altivec_vmaxsb)) {
14630 V2.getOperand(1) == V1) {
14648 switch (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue()) {
14651 case Intrinsic::ppc_vsx_lxvw4x:
14652 case Intrinsic::ppc_vsx_lxvd2x:
14661 switch (cast<ConstantSDNode>(
N->getOperand(1))->getZExtValue()) {
14664 case Intrinsic::ppc_vsx_stxvw4x:
14665 case Intrinsic::ppc_vsx_stxvd2x:
14673 N->getOperand(0).hasOneUse() &&
14689 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
14713 if (!
N->getOperand(0).hasOneUse() &&
14714 !
N->getOperand(1).hasOneUse() &&
14715 !
N->getOperand(2).hasOneUse()) {
14718 SDNode *VCMPrecNode =
nullptr;
14720 SDNode *LHSN =
N->getOperand(0).getNode();
14724 UI->getOperand(1) ==
N->getOperand(1) &&
14725 UI->getOperand(2) ==
N->getOperand(2) &&
14726 UI->getOperand(0) ==
N->getOperand(0)) {
14739 SDNode *FlagUser =
nullptr;
14741 FlagUser ==
nullptr; ++UI) {
14742 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
14755 return SDValue(VCMPrecNode, 0);
14763 cast<ConstantSDNode>(
Cond.getOperand(1))->getZExtValue() ==
14764 Intrinsic::loop_decrement) {
14770 "Counter decrement has more than one use");
14782 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(1))->get();
14783 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
14790 Intrinsic::loop_decrement &&
14796 cast<ConstantSDNode>(LHS.
getOperand(1))->getZExtValue() ==
14797 Intrinsic::loop_decrement &&
14798 isa<ConstantSDNode>(RHS)) {
14800 "Counter decrement comparison is not EQ or NE");
14802 unsigned Val = cast<ConstantSDNode>(RHS)->getZExtValue();
14810 "Counter decrement has more than one use");
14813 N->getOperand(0),
N->getOperand(4));
14822 assert(isDot &&
"Can't compare against a vector result!");
14826 unsigned Val = cast<ConstantSDNode>(RHS)->getZExtValue();
14827 if (Val != 0 && Val != 1) {
14829 return N->getOperand(0);
14832 N->getOperand(0),
N->getOperand(4));
14835 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
14848 switch (cast<ConstantSDNode>(LHS.
getOperand(1))->getZExtValue()) {
14867 N->getOperand(4), CompNode.
getValue(1));
14872 return DAGCombineBuildVector(
N, DCI);
14874 return combineABS(
N, DCI);
14876 return combineVSelect(
N, DCI);
14887 EVT VT =
N->getValueType(0);
14891 !(Divisor.
isPowerOf2() || (-Divisor).isPowerOf2()))
14897 bool IsNegPow2 = (-Divisor).isPowerOf2();
14918 const APInt &DemandedElts,
14920 unsigned Depth)
const {
14922 switch (
Op.getOpcode()) {
14926 if (cast<VTSDNode>(
Op.getOperand(2))->getVT() ==
MVT::i16)
14927 Known.
Zero = 0xFFFF0000;
14931 switch (cast<ConstantSDNode>(
Op.getOperand(0))->getZExtValue()) {
14933 case Intrinsic::ppc_altivec_vcmpbfp_p:
14934 case Intrinsic::ppc_altivec_vcmpeqfp_p:
14935 case Intrinsic::ppc_altivec_vcmpequb_p:
14936 case Intrinsic::ppc_altivec_vcmpequh_p:
14937 case Intrinsic::ppc_altivec_vcmpequw_p:
14938 case Intrinsic::ppc_altivec_vcmpequd_p:
14939 case Intrinsic::ppc_altivec_vcmpequq_p:
14940 case Intrinsic::ppc_altivec_vcmpgefp_p:
14941 case Intrinsic::ppc_altivec_vcmpgtfp_p:
14942 case Intrinsic::ppc_altivec_vcmpgtsb_p:
14943 case Intrinsic::ppc_altivec_vcmpgtsh_p:
14944 case Intrinsic::ppc_altivec_vcmpgtsw_p:
14945 case Intrinsic::ppc_altivec_vcmpgtsd_p:
14946 case Intrinsic::ppc_altivec_vcmpgtsq_p:
14947 case Intrinsic::ppc_altivec_vcmpgtub_p:
14948 case Intrinsic::ppc_altivec_vcmpgtuh_p:
14949 case Intrinsic::ppc_altivec_vcmpgtuw_p:
14950 case Intrinsic::ppc_altivec_vcmpgtud_p:
14951 case Intrinsic::ppc_altivec_vcmpgtuq_p:
14989 uint64_t LoopSize = 0;
14991 for (
auto J = (*I)->begin(), JE = (*I)->end(); J != JE; ++J) {
14992 LoopSize +=
TII->getInstSizeInBytes(*J);
14997 if (LoopSize > 16 && LoopSize <= 32)
15011 if (Constraint.
size() == 1) {
15012 switch (Constraint[0]) {
15030 }
else if (Constraint ==
"wc") {
15032 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
15033 Constraint ==
"wf" || Constraint ==
"ws" ||
15034 Constraint ==
"wi" || Constraint ==
"ww") {
15047 Value *CallOperandVal =
info.CallOperandVal;
15050 if (!CallOperandVal)
15057 else if ((
StringRef(constraint) ==
"wa" ||
15069 switch (*constraint) {
15099 std::pair<unsigned, const TargetRegisterClass *>
15103 if (Constraint.
size() == 1) {
15105 switch (Constraint[0]) {
15108 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
15109 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
15112 return std::make_pair(0U, &PPC::G8RCRegClass);
15113 return std::make_pair(0U, &PPC::GPRCRegClass);
15119 if (Subtarget.
hasSPE()) {
15121 return std::make_pair(0U, &PPC::GPRCRegClass);
15123 return std::make_pair(0U, &PPC::SPERCRegClass);
15126 return std::make_pair(0U, &PPC::F4RCRegClass);
15128 return std::make_pair(0U, &PPC::F8RCRegClass);
15133 return std::make_pair(0U, &PPC::VRRCRegClass);
15136 return std::make_pair(0U, &PPC::CRRCRegClass);
15138 }
else if (Constraint ==
"wc" && Subtarget.
useCRBits()) {
15140 return std::make_pair(0U, &PPC::CRBITRCRegClass);
15141 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
15142 Constraint ==
"wf" || Constraint ==
"wi") &&
15144 return std::make_pair(0U, &PPC::VSRCRegClass);
15145 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.
hasVSX()) {
15147 return std::make_pair(0U, &PPC::VSSRCRegClass);
15149 return std::make_pair(0U, &PPC::VSFRCRegClass);
15150 }
else if (Constraint ==
"lr") {
15152 return std::make_pair(0U, &PPC::LR8RCRegClass);
15154 return std::make_pair(0U, &PPC::LRRCRegClass);
15159 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
15163 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
15164 int VSNum = atoi(Constraint.
data() + 3);
15165 assert(VSNum >= 0 && VSNum <= 63 &&
15166 "Attempted to access a vsr out of range");
15168 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
15169 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
15174 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
15175 int RegNum = atoi(Constraint.
data() + 2);
15176 if (RegNum > 31 || RegNum < 0)
15179 return Subtarget.
hasSPE()
15180 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
15181 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
15183 return Subtarget.
hasSPE()
15184 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
15185 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
15189 std::pair<unsigned, const TargetRegisterClass *> R =
15199 PPC::GPRCRegClass.contains(R.first))
15200 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
15201 PPC::sub_32, &PPC::G8RCRegClass),
15202 &PPC::G8RCRegClass);
15205 if (!R.second &&
StringRef(
"{cc}").equals_lower(Constraint)) {
15206 R.first = PPC::CR0;
15207 R.second = &PPC::CRRCRegClass;
15216 std::string &Constraint,
15217 std::vector<SDValue>&Ops,
15222 if (Constraint.length() > 1)
return;
15224 char Letter = Constraint[0];
15248 if (isShiftedUInt<16, 16>(
Value))
15252 if (isShiftedInt<16, 16>(
Value))
15280 if (Result.getNode()) {
15281 Ops.push_back(Result);
15313 switch (AM.
Scale) {
15344 unsigned Depth = cast<ConstantSDNode>(
Op.getOperand(0))->getZExtValue();
15350 bool isPPC64 = Subtarget.
isPPC64();
15354 SDValue FrameAddr = LowerFRAMEADDR(
Op, DAG);
15364 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
15372 unsigned Depth = cast<ConstantSDNode>(
Op.getOperand(0))->getZExtValue();
15385 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
15387 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
15401 bool isPPC64 = Subtarget.
isPPC64();
15435 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
15453 unsigned Intrinsic)
const {
15454 switch (Intrinsic) {
15455 case Intrinsic::ppc_altivec_lvx:
15456 case Intrinsic::ppc_altivec_lvxl:
15457 case Intrinsic::ppc_altivec_lvebx:
15458 case Intrinsic::ppc_altivec_lvehx:
15459 case Intrinsic::ppc_altivec_lvewx:
15460 case Intrinsic::ppc_vsx_lxvd2x:
15461 case Intrinsic::ppc_vsx_lxvw4x:
15462 case Intrinsic::ppc_vsx_lxvd2x_be:
15463 case Intrinsic::ppc_vsx_lxvw4x_be:
15464 case Intrinsic::ppc_vsx_lxvl:
15465 case Intrinsic::ppc_vsx_lxvll: {
15467 switch (Intrinsic) {
15468 case Intrinsic::ppc_altivec_lvebx:
15471 case Intrinsic::ppc_altivec_lvehx:
15474 case Intrinsic::ppc_altivec_lvewx:
15477 case Intrinsic::ppc_vsx_lxvd2x:
15478 case Intrinsic::ppc_vsx_lxvd2x_be:
15488 Info.ptrVal =
I.getArgOperand(0);
15495 case Intrinsic::ppc_altivec_stvx:
15496 case Intrinsic::ppc_altivec_stvxl:
15497 case Intrinsic::ppc_altivec_stvebx:
15498 case Intrinsic::ppc_altivec_stvehx:
15499 case Intrinsic::ppc_altivec_stvewx:
15500 case Intrinsic::ppc_vsx_stxvd2x:
15501 case Intrinsic::ppc_vsx_stxvw4x:
15502 case Intrinsic::ppc_vsx_stxvd2x_be:
15503 case Intrinsic::ppc_vsx_stxvw4x_be:
15504 case Intrinsic::ppc_vsx_stxvl:
15505 case Intrinsic::ppc_vsx_stxvll: {
15507 switch (Intrinsic) {
15508 case Intrinsic::ppc_altivec_stvebx:
15511 case Intrinsic::ppc_altivec_stvehx:
15514 case Intrinsic::ppc_altivec_stvewx:
15517 case Intrinsic::ppc_vsx_stxvd2x:
15518 case Intrinsic::ppc_vsx_stxvd2x_be:
15528 Info.ptrVal =
I.getArgOperand(1);
15569 return !(BitSize == 0 || BitSize > 64);
15577 return NumBits1 == 64 && NumBits2 == 32;
15585 return NumBits1 == 64 && NumBits2 == 32;
15592 EVT MemVT =
LD->getMemoryVT();
15610 "invalid fpext types");
15629 bool *Fast)
const {
15647 if (Subtarget.
hasVSX()) {
15670 if (
auto *ConstNode = dyn_cast<ConstantSDNode>(
C.getNode())) {
15671 if (!ConstNode->getAPIntValue().isSignedIntN(64))
15679 int64_t Imm = ConstNode->getSExtValue();
15680 unsigned Shift = countTrailingZeros<uint64_t>(Imm);
15684 uint64_t UImm =
static_cast<uint64_t
>(Imm);
15713 if (!
I->hasOneUse())
15717 assert(
User &&
"A single use instruction with no uses.");
15719 switch (
I->getOpcode()) {
15720 case Instruction::FMul: {
15722 if (
User->getOpcode() != Instruction::FSub &&
15723 User->getOpcode() != Instruction::FAdd)
15769 static const MCPhysReg ScratchRegs[] = {
15770 PPC::X12, PPC::LR8, PPC::CTR8, 0
15773 return ScratchRegs;
15777 const Constant *PersonalityFn)
const {
15778 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
15782 const Constant *PersonalityFn)
const {
15788 EVT VT ,
unsigned DefinedValues)
const {
15826 bool LegalOps,
bool OptForSize,
15828 unsigned Depth)
const {
15832 unsigned Opc =
Op.getOpcode();
15833 EVT VT =
Op.getValueType();
15862 N0Cost,
Depth + 1);
15866 N1Cost,
Depth + 1);
15868 if (NegN0 && N0Cost <= N1Cost) {
15870 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
15871 }
else if (NegN1) {
15873 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
15904 bool ForCodeSize)
const {
15935 unsigned Opcode =
N->getOpcode();
15936 unsigned TargetOpcode;
15955 if (
Mask->getZExtValue() == OpSizeInBits - 1)
15961 SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
15991 SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
15998 SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
16017 auto isZextOfCompareWithConstant = [](
SDValue Op) {
16023 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
16024 Cmp.getOperand(0).getValueType() !=
MVT::i64)
16027 if (
auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
16028 int64_t NegConstant = 0 -
Constant->getSExtValue();
16037 bool LHSHasPattern = isZextOfCompareWithConstant(LHS);
16038 bool RHSHasPattern = isZextOfCompareWithConstant(RHS);
16041 if (LHSHasPattern && !RHSHasPattern)
16043 else if (!LHSHasPattern && !RHSHasPattern)
16049 SDValue Z = Cmp.getOperand(0);
16050 auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1));
16053 int64_t NegConstant = 0 -
Constant->getSExtValue();
16055 switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
16066 SDValue AddOrZ = NegConstant != 0 ? Add : Z;
16081 SDValue AddOrZ = NegConstant != 0 ? Add : Z;
16118 if (!GSDN || !ConstNode)
16125 if (!isInt<34>(NewOffset))
16138 SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
16158 DAGCombinerInfo &DCI)
const {
16162 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
16163 return CRTruncValue;
16171 EVT VT =
N->getValueType(0);
16182 DCI.DAG.getTargetConstant(0, dl,
MVT::i32));
16191 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
16201 EltToExtract = EltToExtract ? 0 : 1;
16211 return DCI.DAG.getNode(
16213 DCI.DAG.getTargetConstant(EltToExtract, dl,
MVT::i32));
16218 SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
16222 if (!ConstOpOrElement)
16230 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
16253 return IsAddOne && IsNeg ? VT.
isVector() :
true;
16257 EVT VT =
N->getValueType(0);
16264 if ((MulAmtAbs - 1).isPowerOf2()) {
16268 if (!IsProfitable(IsNeg,
true, VT))
16281 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
16285 if (!IsProfitable(IsNeg,
false, VT))
16306 DAGCombinerInfo &DCI)
const {
16311 EVT VT =
N->getValueType(0);
16314 unsigned Opc =
N->getOpcode();
16316 bool LegalOps = !DCI.isBeforeLegalizeOps();
16340 bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
16357 if (!Callee ||
Callee->isVarArg())
16370 bool PPCTargetLowering::hasBitPreservingFPLogic(
EVT VT)
const {
16371 if (!Subtarget.
hasVSX())
16379 bool PPCTargetLowering::
16380 isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
16385 if (CI->getBitWidth() > 64)
16387 int64_t ConstVal = CI->getZExtValue();
16389 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
16401 SDValue PPCTargetLowering::combineABS(
SDNode *
N, DAGCombinerInfo &DCI)
const {
16404 "Only combine this when P9 altivec supported!");
16405 EVT VT =
N->getValueType(0);
16411 if (
N->getOperand(0).getOpcode() ==
ISD::SUB) {
16414 unsigned SubOpcd0 =
N->getOperand(0)->getOperand(0).getOpcode();
16415 unsigned SubOpcd1 =
N->getOperand(0)->getOperand(1).getOpcode();
16421 N->getOperand(0)->getOperand(0),
16422 N->getOperand(0)->getOperand(1),
16427 if (
N->getOperand(0).getValueType() ==
MVT::v4i32 &&
16428 N->getOperand(0).hasOneUse()) {
16430 N->getOperand(0)->getOperand(0),
16431 N->getOperand(0)->getOperand(1),
16445 DAGCombinerInfo &DCI)
const {
16448 "Only combine this when P9 altivec supported!");
16453 SDValue TrueOpnd =
N->getOperand(1);
16454 SDValue FalseOpnd =
N->getOperand(2);
16455 EVT VT =
N->getOperand(1).getValueType();
16495 CmpOpnd1, CmpOpnd2,
return AArch64::GPR64RegClass contains(Reg)
unsigned const MachineRegisterInfo * MRI
static const unsigned PerfectShuffleTable[6561+1]
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu Simplify well known AMD library false FunctionCallee Callee
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isLoad(int Opcode)
Function Alias Analysis Results
Atomic ordering constants.
SmallVector< MachineOperand, 4 > Cond
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
Module.h This file contains the declarations for the Module class.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static bool isConstantOrUndef(int Op, int Val)
isConstantOrUndef - Op is either an undef node or a ConstantSDNode.
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSMaxIdx, int RHSMinIdx, int RHSMaxIdx, int HalfVec)
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static Instruction * callIntrinsic(IRBuilder<> &Builder, Intrinsic::ID Id)
static bool callsShareTOCBase(const Function *Caller, SDValue Callee, const TargetMachine &TM)
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static bool isFunctionGlobalAddress(SDValue Callee)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool isPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static unsigned getCallOpcode(PPCTargetLowering::CallFlags CFlags, const Function &Caller, const SDValue &Callee, const PPCSubtarget &Subtarget, const TargetMachine &TM)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static void getBaseWithConstantOffset(SDValue Loc, SDValue &Base, int64_t &Offset, SelectionDAG &DAG)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64)
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InFlag, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG)
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue GeneratePerfectShuffle(unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &dl)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > EnableSoftFP128("enable-soft-fp128", cl::desc("temp option to enable soft fp128"), cl::Hidden)
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static bool isSignExtended(MachineInstr &MI, const PPCInstrInfo *TII)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static int getEstimateRefinementSteps(EVT VT, const PPCSubtarget &Subtarget)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
cl::opt< bool > ANDIGlueBug
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is 0.0 or -0.0.
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isSplat(ArrayRef< Value * > VL)
This file describes how to lower LLVM code to machine code.
This defines the Use class.
static bool is64Bit(const char *name)
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set a given bit to 1.
APInt abs() const
Get the absolute value;.
static APInt getAllOnesValue(unsigned numBits)
Get the all-ones value.
bool isNegative() const
Determine sign of this APInt.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Get a value with low bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high bits set.
This class represents an incoming formal argument to a Function.
Class to represent array types.
StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
const BlockAddress * getBlockAddress() const
int64_t getOffset() const
The address of a basic block.
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
MachineFunction & getMachineFunction() const
unsigned AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
unsigned getNextStackOffset() const
getNextStackOffset - Return the next stack offset such that all stack slots satisfy their alignment r...
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
void addLoc(const CCValAssign &V)
CCValAssign - Represent assignment of one arg/retval to a location.
unsigned getLocMemOffset() const
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, unsigned Offset, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, unsigned Offset, MVT LocVT, LocInfo HTP)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
unsigned getValNo() const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
int64_t getSExtValue() const
const APInt & getAPIntValue() const
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
const GlobalValue * getGlobal() const
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalObject * getBaseObject() const
StringRef getSection() const
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
Module * getParent()
Get the module that this global value is contained inside of...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag.
@ Kind_RegDefEarlyClobber
static unsigned getKind(unsigned Flags)
const BasicBlock * getParent() const
bool hasAtomicLoad() const
Return true if this atomic instruction loads from memory.
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
const std::vector< LoopT * > & getSubLoops() const
Return the loops contained entirely within this loop.
unsigned getLoopDepth() const
Return the nesting level of this loop.
block_iterator block_end() const
block_iterator block_begin() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
StringRef getName() const
getName - Get the symbol name.
static mvt_range fixedlen_vector_valuetypes()
uint64_t getScalarSizeInBits() const
@ INVALID_SIMPLE_VALUE_TYPE
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static mvt_range integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static mvt_range fp_valuetypes()
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineModuleInfo & getMMI() const
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
uint64_t getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
const MCContext & getContext() const
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in physical ...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
const SDValue & getChain() const
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
const SDValue & getBasePtr() const
unsigned getAlignment() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
unsigned getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
unsigned getFramePointerSaveOffset() const
getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer.
unsigned getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
void setTailCallSPDelta(int size)
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
bool useLongCalls() const
bool is32BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
const PPCFrameLowering * getFrameLowering() const override
unsigned descriptorTOCAnchorOffset() const
bool useSoftFloat() const
bool use64BitRegs() const
use64BitRegs - Return true if in 64-bit mode or if we should use 64-bit registers in 32-bit mode when...
bool allowsUnalignedFPAccess() const
bool needsSwapsForVSXMemOps() const
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
bool needsTwoConstNR() const
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
const PPCInstrInfo * getInstrInfo() const override
MCRegister getEnvironmentPointerRegister() const
bool useCRBits() const
useCRBits - Return true if we should store and manipulate i1 values in the individual condition regis...
bool hasRecipPrec() const
bool hasInvariantFunctionDescriptors() const
unsigned getCPUDirective() const
getCPUDirective - Returns the -m directive specified for the cpu.
POPCNTDKind hasPOPCNTD() const
bool hasPrefixInstrs() const
bool hasPartwordAtomics() const
bool isLittleEndian() const
bool isTargetLinux() const
bool hasP9Altivec() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
const PPCRegisterInfo * getRegisterInfo() const override
bool has64BitSupport() const
has64BitSupport - Return true if the selected CPU supports 64-bit instructions, regardless of whether...
bool is64BitELFABI() const
bool pairedVectorMemops() const
bool isPredictableSelectIsExpensive() const
bool enableMachineScheduler() const override
Scheduling customization.
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
unsigned descriptorEnvironmentPointerOffset() const
bool hasDirectMove() const
bool hasP8Altivec() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
unsigned getStackProbeSize(MachineFunction &MF) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
const char * getTargetNodeName(unsigned Opcode) const override
getTargetNodeName() - This method returns the name of a target specific DAG node.
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, bool is8bit, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
unsigned getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned AtomicSize, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
void insertSSPDeclarations(Module &M) const override
Inserts necessary declarations for SSP (stack protection) purpose.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always beneficiates from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
Instruction * emitLeadingFence(IRBuilder<> &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
EVT getOptimalMemOpType(const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, unsigned Align=1, MachineMemOperand::Flags Flags=MachineMemOperand::MONone, bool *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool useLoadStackGuardNode() const override
Override to support customized stack guard loading.
bool hasInlineStackProbe(MachineFunction &MF) const override
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=None) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
Instruction * emitTrailingFence(IRBuilder<> &Builder, Instruction *Inst, AtomicOrdering Ord) const override
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
Wrapper class representing virtual and physical registers.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
bool isOnlyUserOf(const SDNode *N) const
Return true if this node is the only use of N.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
const SDValue & getOperand(unsigned Num) const
ArrayRef< SDUse > ops() const
bool isPredecessorOf(const SDNode *N) const
Return true if this node is a predecessor of N.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
op_iterator op_end() const
const SDNodeFlags getFlags() const
op_iterator op_begin() const
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS)
Helper function to make it easier to build Select's if you just have operands and don't want to check...
SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=None, int Offset=0, unsigned TargetFlags=0)
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
const TargetSubtargetInfo & getSubtarget() const
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getTargetFrameIndex(int FI, EVT VT)
SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0)
Test whether V has a splatted value for all the demanded elements.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo)
SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
SDValue getExternalSymbol(const char *Sym, EVT VT)
const DataLayout & getDataLayout() const
MachineFunction & getMachineFunction() const
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond)
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
const TargetLowering & getTargetLoweringInfo() const
SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, uint64_t Size=0, const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
SDValue getRegisterMask(const uint32_t *RegMask)
SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVMContext * getContext() const
SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
const TargetMachine & getTarget() const
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
const_iterator begin() const
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
const_iterator end() const
LLVM_NODISCARD bool empty() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
LLVM_NODISCARD T pop_back_val()
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset is a class to represent an offset with 2 dimensions, named fixed and scalable,...
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
std::enable_if_t< std::numeric_limits< T >::is_signed, bool > getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
LLVM_NODISCARD size_t size() const
size - Get the string size.
A switch()-like statement whose cases are string literals.
LLVM_NODISCARD R Default(T Value)
StringSwitch & Case(StringLiteral S, T Value)
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
void setTargetDAGCombine(ISD::NodeType NT)
Targets should invoke this method for each target independent node that they want to provide a custom...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
const TargetMachine & getTargetMachine() const
void setIndexedStoreAction(unsigned IdxMode, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
virtual MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
void setCondCodeAction(ISD::CondCode CC, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?...
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL, bool LegalTypes=true) const
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
NegatibleCost
Enum that specifies when a float negation is beneficial.
std::vector< ArgListEntry > ArgListTy
void setHasMultipleConditionRegisters(bool hasManyRegs=true)
Tells the code generator that the target has multiple (allocatable) condition registers that can be u...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
virtual void insertSSPDeclarations(Module &M) const
Inserts necessary declarations for SSP (stack protection) purpose.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
void setIndexedLoadAction(unsigned IdxMode, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
virtual bool useLoadStackGuardNode() const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
Primary interface to the complete machine description for the target machine.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
CodeModel::Model getCodeModel() const
Returns the code model.
bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
unsigned EnableAIXExtendedAltivecABI
EnableAIXExtendedAltivecABI - This flag returns true when -vec-extabi is specified.
unsigned NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned NoSignedZerosFPMath
NoSignedZerosFPMath - This flag is enabled when the -enable-no-signed-zeros-fp-math is specified on t...
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
FPOpFusion::FPOpFusionMode AllowFPOpFusion
AllowFPOpFusion - This flag is set by the -fuse-fp-ops=xxx option.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static TypeSize Fixed(ScalarTy MinVal)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
static Type * getVoidTy(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
Base class of all SIMD vector types.
Iterator for intrusive lists based on ilist_node.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Fast
Fast - This calling convention attempts to make calls as fast as possible (e.g.
@ C
C - The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ FLT_ROUNDS_
FLT_ROUNDS_ - Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest 2 Round to ...
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val) This corresponds to "store atomic" instruction.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR
Control flow instructions. These all have token chains.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ BR_JT
BR_JT - Jumptable branch.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum or signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_GOT_FLAG
MO_GOT_FLAG - If this bit is set the symbol reference is to be computed via the GOT.
@ MO_PLT
On a symbol operand "FOO", this indicates that the reference is actually to "FOO@plt".
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set the symbol reference is relative to TLS Initial Exec model.
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ FCTIDUZ
Newer FCTI[D,W]UZ floating-point-to-integer conversion instructions for unsigned integers with round ...
@ ADDI_TLSGD_L_ADDR
G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSGD_L and GET_TLS_ADDR unti...
@ FSQRT
Square root instruction.
@ STRICT_FCFID
Constrained integer-to-floating-point conversion instructions.
@ DYNALLOC
The following two target-specific nodes are used for calls through function pointers in the 64-bit SV...
@ COND_BRANCH
CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This corresponds to the COND_BRANCH pseudo ...
@ VABSD
An SDNode for Power9 vector absolute value difference.
@ STORE_VEC_BE
CHAIN = STORE_VEC_BE CHAIN, VSRC, Ptr - Occurs only for little endian.
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
@ MTVSRZ
Direct move from a GPR to a VSX register (zero)
@ SRL
These nodes represent PPC shifts.
@ VECINSERT
VECINSERT - The PPC vector insert instruction.
@ LXSIZX
GPRC, CHAIN = LXSIZX, CHAIN, Ptr, ByteWidth - This is a load of an integer smaller than 64 bits into ...
@ FNMSUB
FNMSUB - Negated multiply-subtract instruction.
@ RFEBB
CHAIN = RFEBB CHAIN, State - Return from event-based branch.
@ FCTIDZ
FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 operand, producing an f64 value...
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ GET_TLS_ADDR
x3 = GET_TLS_ADDR x3, Symbol - For the general-dynamic TLS model, produces a call to __tls_get_addr(s...
@ FP_TO_UINT_IN_VSR
Floating-point-to-interger conversion instructions.
@ XXSPLTI32DX
XXSPLTI32DX - The PPC XXSPLTI32DX instruction.
@ ANDI_rec_1_EQ_BIT
i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the eq or gt bit of CR0 after ex...
@ FRE
Reciprocal estimate instructions (unary FP ops).
@ ADDIS_GOT_TPREL_HA
G8RC = ADDIS_GOT_TPREL_HA x2, Symbol - Used by the initial-exec TLS model, produces an ADDIS8 instruc...
@ CLRBHRB
CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer.
@ SINT_VEC_TO_FP
Extract a subvector from signed integer vector and convert to FP.
@ EXTRACT_SPE
Extract SPE register component, second argument is high or low.
@ XXSWAPD
VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little endian.
@ ADDI_TLSLD_L_ADDR
G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSLD_L and GET_TLSLD_ADDR un...
@ ATOMIC_CMP_SWAP_8
ATOMIC_CMP_SWAP - the exact same as the target-independent nodes except they ensure that the compare ...
@ ST_VSR_SCAL_INT
Store scalar integers from VSR.
@ VCMP
RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP* instructions.
@ BCTRL
CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a BCTRL instruction.
@ BUILD_SPE64
BUILD_SPE64 and EXTRACT_SPE are analogous to BUILD_PAIR and EXTRACT_ELEMENT but take f64 arguments in...
@ LFIWZX
GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point load which zero-extends from a 32-bit inte...
@ SCALAR_TO_VECTOR_PERMUTED
PowerPC instructions that have SCALAR_TO_VECTOR semantics tend to place the value into the least sign...
@ EXTRACT_VSX_REG
EXTRACT_VSX_REG = Extract one of the underlying vsx registers of an accumulator or pair register.
@ STXSIX
STXSIX - The STXSI[bh]X instruction.
@ MAT_PCREL_ADDR
MAT_PCREL_ADDR = Materialize a PC Relative address.
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ XXSPLT
XXSPLT - The PPC VSX splat instructions.
@ TOC_ENTRY
GPRC = TOC_ENTRY GA, TOC Loads the entry for GA from the TOC, where the TOC base is given by the last...
@ XXPERMDI
XXPERMDI - The PPC XXPERMDI instruction.
@ ADDIS_DTPREL_HA
G8RC = ADDIS_DTPREL_HA x3, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction t...
@ ADD_TLS
G8RC = ADD_TLS G8RReg, Symbol - Used by the initial-exec TLS model, produces an ADD instruction that ...
@ MTVSRA
Direct move from a GPR to a VSX register (algebraic)
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_GOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ ADDI_DTPREL_L
G8RC = ADDI_DTPREL_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction ...
@ BCTRL_LOAD_TOC
CHAIN,FLAG = BCTRL(CHAIN, ADDR, INFLAG) - The combination of a bctrl instruction and the TOC reload r...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ FCFID
FCFID - The FCFID instruction, taking an f64 operand and producing and f64 value containing the FP re...
@ CR6SET
ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls
@ LBRX
GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a byte-swapping load instruction.
@ LD_VSX_LH
VSRC, CHAIN = LD_VSX_LH CHAIN, Ptr - This is a floating-point load of a v2f32 value into the lower ha...
@ PROBED_ALLOCA
To avoid stack clash, allocation is performed by block and each block is probed.
@ XXMFACC
XXMFACC = This corresponds to the xxmfacc instruction.
@ ADDIS_TLSGD_HA
G8RC = ADDIS_TLSGD_HA x2, Symbol - For the general-dynamic TLS model, produces an ADDIS8 instruction ...
@ ACC_BUILD
ACC_BUILD = Build an accumulator register from 4 VSX registers.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ LXVD2X
VSRC, CHAIN = LXVD2X_LE CHAIN, Ptr - Occurs only for little endian.
@ CALL
CALL - A direct function call.
@ MTCTR
CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a MTCTR instruction.
@ TC_RETURN
TC_RETURN - A tail call return.
@ STFIWX
STFIWX - The STFIWX instruction.
@ LD_SPLAT
VSRC, CHAIN = LD_SPLAT, CHAIN, Ptr - a splatting load memory instructions such as LXVDSX,...
@ VCMP_rec
RESVEC, OUTFLAG = VCMP_rec(LHS, RHS, OPC) - Represents one of the altivec VCMP*_rec instructions.
@ MFFS
F8RC = MFFS - This moves the FPSCR (not modeled) into the register.
@ PADDI_DTPREL
G8RC = PADDI_DTPREL x3, Symbol - For the pc-rel based local-dynamic TLS model, produces a PADDI8 inst...
@ BUILD_FP128
Direct move of 2 consecutive GPR to a VSX register.
@ VEXTS
VEXTS, ByteWidth - takes an input in VSFRC and produces an output in VSFRC that is sign-extended from...
@ TLS_LOCAL_EXEC_MAT_ADDR
TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address when using local exec access ...
@ VPERM
VPERM - The PPC VPERM Instruction.
@ ADDIS_TLSLD_HA
G8RC = ADDIS_TLSLD_HA x2, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction th...
@ XXSPLTI_SP_TO_DP
XXSPLTI_SP_TO_DP - The PPC VSX splat instructions for immediates for converting immediate single prec...
@ GET_TLSLD_ADDR
x3 = GET_TLSLD_ADDR x3, Symbol - For the local-dynamic TLS model, produces a call to __tls_get_addr(s...
@ ADDI_TLSGD_L
x3 = ADDI_TLSGD_L G8RReg, Symbol - For the general-dynamic TLS model, produces an ADDI8 instruction t...
@ DYNAREAOFFSET
This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to compute an offset from native ...
@ PAIR_BUILD
PAIR_BUILD = Build a vector pair register from 2 VSX registers.
@ STRICT_FADDRTZ
Constrained floating point add in round-to-zero mode.
@ FTSQRT
Test instruction for software square root.
@ FP_EXTEND_HALF
FP_EXTEND_HALF(VECTOR, IDX) - Custom extend upper (IDX=0) half or lower (IDX=1) half of v4f32 to v2f6...
@ RET_FLAG
Return with a flag operand, matched by 'blr'.
@ CMPB
The CMPB instruction (takes two operands of i32 or i64).
@ VECSHL
VECSHL - The PPC vector shift left instruction.
@ ADDI_TLSLD_L
x3 = ADDI_TLSLD_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction tha...
@ FADDRTZ
F8RC = FADDRTZ F8RC, F8RC - This is an FADD done with rounding towards zero.
@ XSMAXCDP
XSMAXCDP, XSMINCDP - C-type min/max instructions.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
@ EXTSWSLI
EXTSWSLI = The PPC extswsli instruction, which does an extend-sign word and shift left immediate.
@ STXVD2X
CHAIN = STXVD2X CHAIN, VSRC, Ptr - Occurs only for little endian.
@ UINT_VEC_TO_FP
Extract a subvector from unsigned integer vector and convert to FP.
@ LXVRZX
LXVRZX - Load VSX Vector Rightmost and Zero Extend This node represents v1i128 BUILD_VECTOR of a zero...
@ MFBHRBE
GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch history rolling buffer entry.
@ FCFIDU
Newer FCFID[US] integer-to-floating-point conversion instructions for unsigned integers and single-pr...
@ FSEL
FSEL - Traditional three-operand fsel node.
@ SWAP_NO_CHAIN
An SDNode for swaps that are not associated with any loads/stores and thereby have no chain.
@ LOAD_VEC_BE
VSRC, CHAIN = LOAD_VEC_BE CHAIN, Ptr - Occurs only for little endian.
@ LFIWAX
GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point load which sign-extends from a 32-bit inte...
@ STBRX
CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a byte-swapping store instruction.
@ LD_GOT_TPREL_L
G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec TLS model, produces a LD instruction ...
@ MFVSR
Direct move from a VSX register to a GPR.
@ TLS_DYNAMIC_MAT_PCREL_ADDR
TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for TLS global address when using dyna...
@ Hi
Hi/Lo - These represent the high and low 16-bit parts of a global address respectively.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
@ XTY_ER
External reference.
CodeModel::Model getCodeModel()
const_iterator end(StringRef path)
Get end iterator over path.
This class represents lattice values for constants.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
static bool isIndirectCall(const MachineInstr &MI)
constexpr bool isUInt< 16 >(uint64_t x)
STATISTIC(NumFunctions, "Total number of functions")
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isInt< 32 >(int64_t x)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
constexpr bool isInt< 16 >(int64_t x)
uint32_t FloatToBits(float Float)
This function takes a float and returns the bit equivalent 32-bit integer.
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
uint64_t PowerOf2Floor(uint64_t A)
Returns the power of two which is less than or equal to the given value.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
unsigned countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1.
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Align max(MaybeAlign Lhs, Align Rhs)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Mod
The access may modify the value stored in memory.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
@ Mul
Product of integers.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
A and B are either alignments or offsets.
unsigned M0(unsigned Val)
ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr unsigned BitWidth
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Align commonAlignment(Align A, Align B)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble() LLVM_READNONE
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
bool isInConsecutiveRegs() const
unsigned getByValSize() const
bool isInConsecutiveRegsLast() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
bool hasNoSignedZeros() const
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg If BaseGV is null...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
bool isAfterLegalizeDAG() const
void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)